diff --git a/include/BLE.cpp b/include/BLE.cpp index 713cf0e..627108a 100644 --- a/include/BLE.cpp +++ b/include/BLE.cpp @@ -6,10 +6,10 @@ #include "defines.h" #include #include "bmHTTP.hpp" +#include +#include "setup.hpp" std::atomic flag_scan_requested{false}; -std::atomic credsGiven{false}; -std::atomic tokenGiven{false}; std::atomic isBLEClientConnected{false}; std::atomic scanBlock{false}; std::atomic finalAuth{false}; @@ -29,7 +29,14 @@ std::atomic credsChar = nullptr; std::atomic tokenChar = nullptr; std::atomic ssidRefreshChar = nullptr; +static QueueHandle_t BLE_event_queue = NULL; +static TaskHandle_t BLE_manager_task_handle = NULL; + +SemaphoreHandle_t BLE_Queue_Shutdown_Semaphore = NULL; + NimBLEAdvertising* initBLE() { + BLE_event_queue = xQueueCreate(10, sizeof(BLE_event_type_t)); + xTaskCreate(BLE_manager_task, "BLE", 8192, NULL, 5, &BLE_manager_task_handle); finalAuth = false; NimBLEDevice::init("BlindMaster-C6"); @@ -120,126 +127,18 @@ void notifyAuthStatus(bool success) { tmpConfChar->notify(); tmpConfChar->setValue(""); // Clear value after notify } - -bool BLEtick(NimBLEAdvertising* pAdvertising) { - printf("BleTick\n"); - if(flag_scan_requested) { - flag_scan_requested = false; - if (!scanBlock) { - scanBlock = true; - printf("Scanning WiFi...\n"); - bmWiFi.scanAndUpdateSSIDList(); - } - else printf("Duplicate scan request\n"); - } - else if (credsGiven) { - std::string tmpSSID; - std::string tmpUNAME; - std::string tmpPASS; - wifi_auth_mode_t tmpAUTH; - { - std::lock_guard lock(dataMutex); - tmpSSID = SSID; - tmpUNAME = UNAME; - tmpPASS = PASS; - tmpAUTH = auth; - credsGiven = false; - } - - bool wifiConnect; - if (tmpAUTH == WIFI_AUTH_WPA2_ENTERPRISE || tmpAUTH == WIFI_AUTH_WPA3_ENTERPRISE) - wifiConnect = bmWiFi.attemptConnect(tmpSSID.c_str(), tmpUNAME.c_str(), tmpPASS.c_str(), tmpAUTH); - else wifiConnect = bmWiFi.attemptConnect(tmpSSID.c_str(), tmpPASS.c_str(), tmpAUTH); - if (!wifiConnect) { - // notify errored - notifyConnectionStatus(false); - return false; - } - - nvs_handle_t WiFiHandle; - esp_err_t err = nvs_open(nvsWiFi, NVS_READWRITE, &WiFiHandle); - if (err != ESP_OK) { - printf("ERROR Saving Credentials\n"); - // notify errored - notifyConnectionStatus(false); - return false; - } - else { - err = nvs_set_str(WiFiHandle, ssidTag, tmpSSID.c_str()); - if (err == ESP_OK) err = nvs_set_str(WiFiHandle, passTag, tmpPASS.c_str()); - if (err == ESP_OK) err = nvs_set_str(WiFiHandle, unameTag, tmpUNAME.c_str()); - if (err == ESP_OK) err = nvs_set_u8(WiFiHandle, authTag, (uint8_t)tmpAUTH); - if (err == ESP_OK) nvs_commit(WiFiHandle); - nvs_close(WiFiHandle); - } - if (err == ESP_OK) { - // notify connected - notifyConnectionStatus(true); - } - else { - // notify connected - notifyConnectionStatus(false); - } - } - else if (tokenGiven) { - tokenGiven = false; - if (!bmWiFi.isConnected()) { - printf("ERROR: token given without WiFi connection\n"); - notifyAuthStatus(false); - return false; - } - - // HTTP request to verify device with token - std::string tmpTOKEN; - { - std::lock_guard lock(dataMutex); - tmpTOKEN = TOKEN; - } - - cJSON *responseRoot; - bool success = httpGET("verify_device", tmpTOKEN, responseRoot); - if (!success) return false; - success = false; - - if (responseRoot != NULL) { - cJSON *tokenItem = cJSON_GetObjectItem(responseRoot, "token"); - if (cJSON_IsString(tokenItem) && tokenItem->valuestring != NULL) { - printf("New token received: %s\n", tokenItem->valuestring); - - // Save token to NVS - nvs_handle_t AuthHandle; - esp_err_t nvs_err = nvs_open(nvsAuth, NVS_READWRITE, &AuthHandle); - if (nvs_err == ESP_OK) { - nvs_err = nvs_set_str(AuthHandle, tokenTag, tokenItem->valuestring); - if (nvs_err == ESP_OK) { - nvs_commit(AuthHandle); - success = true; - webToken = tokenItem->valuestring; - } - else printf("ERROR: could not save webToken to NVS\n"); - nvs_close(AuthHandle); - } - else printf("ERROR: Couldn't open NVS for auth token\n"); - } - cJSON_Delete(responseRoot); - } - else printf("Failed to parse JSON response\n"); - - finalAuth = true; - notifyAuthStatus(success); - if (success) NimBLEDevice::deinit(true); // deinitialize BLE - return success; - } - return false; -} - void reset() { + BLE_Queue_Shutdown_Semaphore = xSemaphoreCreateBinary(); + BLE_event_type_t event_type = EVENT_SHUTDOWN; + xQueueSend(BLE_event_queue, &event_type, portMAX_DELAY); + xSemaphoreTake(BLE_Queue_Shutdown_Semaphore, portMAX_DELAY); + vQueueDelete(BLE_event_queue); esp_wifi_scan_stop(); if (!finalAuth) esp_wifi_disconnect(); scanBlock = false; - flag_scan_requested = false; - credsGiven = false; - tokenGiven = false; + vSemaphoreDelete(BLE_Queue_Shutdown_Semaphore); + BLE_event_queue = xQueueCreate(10, sizeof(BLE_event_type_t)); + xTaskCreate(BLE_manager_task, "BLE", 8192, NULL, 5, &BLE_manager_task_handle); } void MyServerCallbacks::onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo) { @@ -259,89 +158,231 @@ void MyCharCallbacks::onRead(NimBLECharacteristic* pChar, NimBLEConnInfo& connIn } void MyCharCallbacks::onWrite(NimBLECharacteristic* pChar, NimBLEConnInfo& connInfo) { - std::string val = pChar->getValue(); - std::string uuidStr = pChar->getUUID().toString(); - - printf("onWrite called! UUID: %s, Value length: %d\n", uuidStr.c_str(), val.length()); - - // Load atomic pointers for comparison - NimBLECharacteristic* currentCredsChar = credsChar.load(); - NimBLECharacteristic* currentTokenChar = tokenChar.load(); - NimBLECharacteristic* currentRefreshChar = ssidRefreshChar.load(); - - // Check which characteristic was written to - if (pChar == currentCredsChar) { - // Credentials JSON characteristic - if (val.length() > 0) { - printf("Received JSON: %s\n", val.c_str()); + std::string val = pChar->getValue(); + std::string uuidStr = pChar->getUUID().toString(); + + printf("onWrite called! UUID: %s, Value length: %d\n", uuidStr.c_str(), val.length()); + + // Load atomic pointers for comparison + NimBLECharacteristic* currentCredsChar = credsChar.load(); + NimBLECharacteristic* currentTokenChar = tokenChar.load(); + NimBLECharacteristic* currentRefreshChar = ssidRefreshChar.load(); + + // Check which characteristic was written to + if (pChar == currentCredsChar) { + // Credentials JSON characteristic + if (val.length() > 0) { + printf("Received JSON: %s\n", val.c_str()); + + // Parse JSON using cJSON + cJSON *root = cJSON_Parse(val.c_str()); + if (root != NULL) { + cJSON *ssid = cJSON_GetObjectItem(root, "ssid"); + cJSON *password = cJSON_GetObjectItem(root, "password"); + cJSON *authType = cJSON_GetObjectItem(root, "auth"); + cJSON *uname = cJSON_GetObjectItem(root, "uname"); - // Parse JSON using cJSON - cJSON *root = cJSON_Parse(val.c_str()); - if (root != NULL) { - cJSON *ssid = cJSON_GetObjectItem(root, "ssid"); - cJSON *password = cJSON_GetObjectItem(root, "password"); - cJSON *authType = cJSON_GetObjectItem(root, "auth"); - cJSON *uname = cJSON_GetObjectItem(root, "uname"); - - bool enterprise = false; - bool open = false; - bool error = false; - if (cJSON_IsNumber(authType)) { - enterprise = authType->valueint == WIFI_AUTH_WPA2_ENTERPRISE || - authType->valueint == WIFI_AUTH_WPA3_ENTERPRISE; - open = authType->valueint == WIFI_AUTH_OPEN; - error = authType->valueint < 0 || authType->valueint >= WIFI_AUTH_MAX; - } - else error = true; - if (error) { - printf("ERROR: Invalid Auth mode passed in with JSON.\n"); - credsGiven = false; - cJSON_Delete(root); - return; - } - - bool ssidPresent = cJSON_IsString(ssid) && ssid->valuestring != NULL; - bool passPresent = cJSON_IsString(password) && password->valuestring != NULL; - bool unamePresent = cJSON_IsString(uname) && uname->valuestring != NULL; - bool tempCredsGiven = ssidPresent && (passPresent || open) && - (unamePresent || !enterprise); - - if (tempCredsGiven) { - printf("Received credentials, will attempt connection\n"); + bool enterprise = false; + bool open = false; + bool error = false; + if (cJSON_IsNumber(authType)) { + enterprise = authType->valueint == WIFI_AUTH_WPA2_ENTERPRISE || + authType->valueint == WIFI_AUTH_WPA3_ENTERPRISE; + open = authType->valueint == WIFI_AUTH_OPEN; + error = authType->valueint < 0 || authType->valueint >= WIFI_AUTH_MAX; + } + else error = true; + if (error) { + printf("ERROR: Invalid Auth mode passed in with JSON.\n"); + cJSON_Delete(root); + return; + } + + bool ssidPresent = cJSON_IsString(ssid) && ssid->valuestring != NULL; + bool passPresent = cJSON_IsString(password) && password->valuestring != NULL; + bool unamePresent = cJSON_IsString(uname) && uname->valuestring != NULL; + bool tempCredsGiven = ssidPresent && (passPresent || open) && + (unamePresent || !enterprise); + + if (tempCredsGiven) { + printf("Received credentials, will attempt connection\n"); + { std::lock_guard lock(dataMutex); auth = (wifi_auth_mode_t)(authType->valueint); SSID = ssid->valuestring; PASS = passPresent ? password->valuestring : ""; UNAME = unamePresent ? uname->valuestring : ""; - credsGiven = tempCredsGiven; // update the global flag. } - else printf("ERROR: Did not receive necessary credentials.\n"); - cJSON_Delete(root); - } else { - printf("Failed to parse JSON\n"); - credsGiven = false; + BLE_event_type_t event_type = EVENT_CREDS_GIVEN; + if (xQueueSend(BLE_event_queue, &event_type, pdMS_TO_TICKS(10)) == pdPASS) + printf("Successfully added credsGiven to event queue\n"); + else printf("CredsGiven event queue addition failed\n"); } + else printf("ERROR: Did not receive necessary credentials.\n"); + cJSON_Delete(root); + } else { + printf("Failed to parse JSON\n"); } } - else if (pChar == currentTokenChar) { - if (val.length() > 0) { - printf("Received Token: %s\n", val.c_str()); + } + else if (pChar == currentTokenChar) { + if (val.length() > 0) { + printf("Received Token: %s\n", val.c_str()); + { std::lock_guard lock(dataMutex); TOKEN = val; - tokenGiven = true; } + BLE_event_type_t event_type = EVENT_TOKEN_GIVEN; + if (xQueueSend(BLE_event_queue, &event_type, pdMS_TO_TICKS(10)) == pdPASS) + printf("Successfully added tokenGiven to event queue\n"); + else printf("TokenGiven event queue addition failed\n"); } - else if (pChar == currentRefreshChar) { - if (val == "Start") { - // Refresh characteristic + } + else if (pChar == currentRefreshChar) { + if (val == "Start") { + // Refresh characteristic + BLE_event_type_t event_type = EVENT_SCAN_REQUESTED; + if (xQueueSend(BLE_event_queue, &event_type, pdMS_TO_TICKS(10)) == pdPASS) { + printf("Event queue addition success for scan start\n"); + } + else printf("Scan start event queue addition failed\n"); + } + else if (val == "Done") { + printf("Data read complete\n"); + scanBlock = false; + } + } + else printf("Unknown UUID: %s\n", uuidStr.c_str()); +} + +void BLE_manager_task(void *pvParameters) { + BLE_event_type_t received_event_type; + + while (true) { + if (xQueueReceive(BLE_event_queue, &received_event_type, portMAX_DELAY)) { + if (received_event_type == EVENT_SCAN_REQUESTED) { printf("Refresh Requested\n"); - flag_scan_requested = true; + if (!scanBlock) { + scanBlock = true; + printf("Scanning WiFi...\n"); + bmWiFi.scanAndUpdateSSIDList(); + } + else printf("Duplicate scan request\n"); } - else if (val == "Done") { - printf("Data read complete\n"); - scanBlock = false; + else if (received_event_type == EVENT_TOKEN_GIVEN) { + if (tokenCheck()) { + vQueueDelete(BLE_event_queue); + if (setupTaskHandle != NULL) { + xTaskNotifyGive(setupTaskHandle); + printf("Setup complete.\n"); + } + break; + } } + else if (received_event_type == EVENT_CREDS_GIVEN) + attemptUseWiFiCreds(); + else if (received_event_type == EVENT_SHUTDOWN) break; } - else printf("Unknown UUID: %s\n", uuidStr.c_str()); - } \ No newline at end of file + } + xSemaphoreGive(BLE_Queue_Shutdown_Semaphore); + vTaskDelete(NULL); +} + +bool tokenCheck() { + if (!bmWiFi.isConnected()) { + printf("ERROR: token given without WiFi connection\n"); + notifyAuthStatus(false); + return false; + } + + // HTTP request to verify device with token + std::string tmpTOKEN; + { + std::lock_guard lock(dataMutex); + tmpTOKEN = TOKEN; + } + + cJSON *responseRoot; + bool success = httpGET("verify_device", tmpTOKEN, responseRoot); + if (!success) return false; + success = false; + + if (responseRoot != NULL) { + cJSON *tokenItem = cJSON_GetObjectItem(responseRoot, "token"); + if (cJSON_IsString(tokenItem) && tokenItem->valuestring != NULL) { + printf("New token received: %s\n", tokenItem->valuestring); + + // Save token to NVS + nvs_handle_t AuthHandle; + esp_err_t nvs_err = nvs_open(nvsAuth, NVS_READWRITE, &AuthHandle); + if (nvs_err == ESP_OK) { + nvs_err = nvs_set_str(AuthHandle, tokenTag, tokenItem->valuestring); + if (nvs_err == ESP_OK) { + nvs_commit(AuthHandle); + success = true; + webToken = tokenItem->valuestring; + } + else printf("ERROR: could not save webToken to NVS\n"); + nvs_close(AuthHandle); + } + else printf("ERROR: Couldn't open NVS for auth token\n"); + } + cJSON_Delete(responseRoot); + } + else printf("Failed to parse JSON response\n"); + + finalAuth = true; + notifyAuthStatus(success); + if (success) NimBLEDevice::deinit(true); // deinitialize BLE + return success; +} + +bool attemptUseWiFiCreds() { + std::string tmpSSID; + std::string tmpUNAME; + std::string tmpPASS; + wifi_auth_mode_t tmpAUTH; + { + std::lock_guard lock(dataMutex); + tmpSSID = SSID; + tmpUNAME = UNAME; + tmpPASS = PASS; + tmpAUTH = auth; + } + + bool wifiConnect; + if (tmpAUTH == WIFI_AUTH_WPA2_ENTERPRISE || tmpAUTH == WIFI_AUTH_WPA3_ENTERPRISE) + wifiConnect = bmWiFi.attemptConnect(tmpSSID.c_str(), tmpUNAME.c_str(), tmpPASS.c_str(), tmpAUTH); + else wifiConnect = bmWiFi.attemptConnect(tmpSSID.c_str(), tmpPASS.c_str(), tmpAUTH); + if (!wifiConnect) { + // notify errored + notifyConnectionStatus(false); + return; + } + + nvs_handle_t WiFiHandle; + esp_err_t err = nvs_open(nvsWiFi, NVS_READWRITE, &WiFiHandle); + if (err != ESP_OK) { + printf("ERROR Saving Credentials\n"); + // notify errored + notifyConnectionStatus(false); + return; + } + else { + err = nvs_set_str(WiFiHandle, ssidTag, tmpSSID.c_str()); + if (err == ESP_OK) err = nvs_set_str(WiFiHandle, passTag, tmpPASS.c_str()); + if (err == ESP_OK) err = nvs_set_str(WiFiHandle, unameTag, tmpUNAME.c_str()); + if (err == ESP_OK) err = nvs_set_u8(WiFiHandle, authTag, (uint8_t)tmpAUTH); + if (err == ESP_OK) nvs_commit(WiFiHandle); + nvs_close(WiFiHandle); + } + if (err == ESP_OK) { + // notify connected + notifyConnectionStatus(true); + } + else { + // notify connected + notifyConnectionStatus(false); + } +} \ No newline at end of file diff --git a/include/BLE.hpp b/include/BLE.hpp index 8a3d34f..803f40a 100644 --- a/include/BLE.hpp +++ b/include/BLE.hpp @@ -23,6 +23,17 @@ class MyCharCallbacks : public NimBLECharacteristicCallbacks { }; NimBLEAdvertising* initBLE(); -bool BLEtick(NimBLEAdvertising* pAdvertising); + +void BLE_manager_task(void *pvParameters); + +// Event Types +typedef enum { + EVENT_SCAN_REQUESTED, + EVENT_TOKEN_GIVEN, + EVENT_CREDS_GIVEN, + EVENT_SHUTDOWN +} BLE_event_type_t; + +bool tokenCheck(); #endif \ No newline at end of file diff --git a/include/bmEvents.cpp b/include/bmEvents.cpp new file mode 100644 index 0000000..1269004 --- /dev/null +++ b/include/bmEvents.cpp @@ -0,0 +1,44 @@ +#include "bmEvents.hpp" +#include +#include + +// blueprint for sending events... maybe I never use this. We'll see. +// bool send_app_event(app_event_t *event, QueueHandle_t event_queue) { +// if (event_queue == NULL) return false; + +// // A. Are we in an Interrupt Service Routine (Hardware context)? +// if (xPortInIsrContext()) { +// BaseType_t xHigherPriorityTaskWoken = pdFALSE; + +// // Use the "FromISR" version +// BaseType_t result = xQueueSendFromISR(event_queue, event, &xHigherPriorityTaskWoken); + +// // This is crucial for "Instant Wakeup" +// if (result == pdPASS) portYIELD_FROM_ISR(xHigherPriorityTaskWoken); +// return (result == pdPASS); +// } + +// // B. Are we in a Standard Task (WiFi/BLE Callback context)? +// else { +// // Use the standard version +// // 10 ticks wait time is arbitrary; allows a small buffer if queue is full +// return (xQueueSend(event_queue, event, pdMS_TO_TICKS(10)) == pdPASS); +// } +// } + + +// blueprint for deleting more complex event queues +// void deinit_BLE_event_queue(QueueHandle_t& event_queue) { +// if (event_queue != NULL) { +// app_event_t temp_event; +// while (xQueueReceive(event_queue, &temp_event, 0) == pdTRUE) { +// if (temp_event.data != NULL) free(temp_event.data); +// } + +// vQueueDelete(event_queue); + +// event_queue = NULL; + +// printf("Event queue deleted.\n"); +// } +// } \ No newline at end of file diff --git a/include/bmEvents.hpp b/include/bmEvents.hpp new file mode 100644 index 0000000..e1eff23 --- /dev/null +++ b/include/bmEvents.hpp @@ -0,0 +1,9 @@ +#ifndef BM_EVENTS_H +#define BM_EVENTS_H +#include + +// bool send_app_event(app_event_t *event); + +// void deinit_event_queue(QueueHandle_t& event_queue); + +#endif \ No newline at end of file diff --git a/include/servo.cpp b/include/servo.cpp index 1ff88d4..b81d61f 100644 --- a/include/servo.cpp +++ b/include/servo.cpp @@ -23,7 +23,7 @@ void servoInit() { ledc_timer.timer_num = LEDC_TIMER_0; ledc_timer.duty_resolution = LEDC_TIMER_16_BIT; ledc_timer.freq_hz = 50; - ledc_timer.clk_cfg = LEDC_AUTO_CLK; + ledc_timer.clk_cfg = LEDC_USE_RC_FAST_CLK; ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer)); // LEDC channel configuration @@ -35,7 +35,9 @@ void servoInit() { ledc_channel.gpio_num = servoPin; ledc_channel.duty = offSpeed; // Start off ledc_channel.hpoint = 0; + ledc_channel.sleep_mode = LEDC_SLEEP_MODE_KEEP_ALIVE; ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel)); + gpio_sleep_sel_dis(servoPin); // Configure servo power switch pin as output gpio_set_direction(servoSwitch, GPIO_MODE_OUTPUT); diff --git a/include/setup.cpp b/include/setup.cpp index 74dba76..a138aae 100644 --- a/include/setup.cpp +++ b/include/setup.cpp @@ -6,16 +6,15 @@ #include "bmHTTP.hpp" #include "socketIO.hpp" +TaskHandle_t setupTaskHandle = NULL; + void initialSetup() { printf("Entered Setup\n"); NimBLEAdvertising* pAdv = initBLE(); - - while (!BLEtick(pAdv)) { - vTaskDelay(pdMS_TO_TICKS(100)); - } + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); } -void setupLoop() { +void setupLoop(void *pvParameters) { bool initSuccess = false; while(!initSuccess) { nvs_handle_t WiFiHandle; diff --git a/include/setup.hpp b/include/setup.hpp index 4e5ae4c..f75f527 100644 --- a/include/setup.hpp +++ b/include/setup.hpp @@ -1,7 +1,9 @@ #ifndef SETUP_H #define SETUP_H +extern TaskHandle_t setupTaskHandle; + void initialSetup(); -void setupLoop(); +void setupLoop(void *pvParameters); #endif \ No newline at end of file diff --git a/sdkconfig.seeed_xiao_esp32c6 b/sdkconfig.seeed_xiao_esp32c6 index ca0ec4e..dbe3ede 100644 --- a/sdkconfig.seeed_xiao_esp32c6 +++ b/sdkconfig.seeed_xiao_esp32c6 @@ -1153,7 +1153,6 @@ CONFIG_ESP_TLS_DYN_BUF_STRATEGY_SUPPORTED=y CONFIG_ESP_COEX_ENABLED=y CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y # CONFIG_ESP_COEX_POWER_MANAGEMENT is not set -# CONFIG_ESP_COEX_GPIO_DEBUG is not set # end of Wireless Coexistence # @@ -1294,6 +1293,7 @@ CONFIG_SPI_SLAVE_ISR_IN_IRAM=y # ESP-Driver:USB Serial/JTAG Configuration # CONFIG_USJ_ENABLE_USB_SERIAL_JTAG=y +# CONFIG_USJ_NO_AUTO_LS_ON_CONNECTION is not set # end of ESP-Driver:USB Serial/JTAG Configuration # @@ -1424,6 +1424,7 @@ CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=0 # CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set # CONFIG_ESP_SLEEP_DEBUG is not set CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y +# CONFIG_ESP_SLEEP_EVENT_CALLBACKS is not set # end of Sleep Config # @@ -1528,6 +1529,7 @@ CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y # CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 CONFIG_ESP_PHY_MAX_TX_POWER=20 +CONFIG_ESP_PHY_MAC_BB_PD=y # CONFIG_ESP_PHY_REDUCE_TX_POWER is not set # CONFIG_ESP_PHY_ENABLE_CERT_TEST is not set CONFIG_ESP_PHY_RF_CAL_PARTIAL=y @@ -1545,11 +1547,18 @@ CONFIG_ESP_PHY_IRAM_OPT=y # Power Management # CONFIG_PM_SLEEP_FUNC_IN_IRAM=y -# CONFIG_PM_ENABLE is not set +CONFIG_PM_ENABLE=y +CONFIG_PM_DFS_INIT_AUTO=y +# CONFIG_PM_PROFILING is not set +CONFIG_PM_TRACE=y CONFIG_PM_SLP_IRAM_OPT=y +CONFIG_PM_RTOS_IDLE_OPT=y +CONFIG_PM_SLP_DISABLE_GPIO=y CONFIG_PM_SLP_DEFAULT_PARAMS_OPT=y +CONFIG_PM_LIGHTSLEEP_RTC_OSC_CAL_INTERVAL=1 CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP=y -# CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP is not set +CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y +# CONFIG_PM_LIGHT_SLEEP_CALLBACKS is not set # end of Power Management # @@ -1708,6 +1717,7 @@ CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=y # CONFIG_ESP_WIFI_GCMP_SUPPORT is not set CONFIG_ESP_WIFI_GMAC_SUPPORT=y CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y +# CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP is not set # CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y @@ -1830,6 +1840,8 @@ CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 # CONFIG_FREERTOS_USE_TRACE_FACILITY is not set # CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES is not set # CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +CONFIG_FREERTOS_USE_TICKLESS_IDLE=y +CONFIG_FREERTOS_IDLE_TIME_BEFORE_SLEEP=3 # CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set # end of Kernel @@ -1909,6 +1921,7 @@ CONFIG_IEEE802154_CCA_THRESHOLD=-60 CONFIG_IEEE802154_PENDING_TABLE_SIZE=20 # CONFIG_IEEE802154_MULTI_PAN_ENABLE is not set CONFIG_IEEE802154_TIMING_OPTIMIZATION=y +# CONFIG_IEEE802154_SLEEP_ENABLE is not set # CONFIG_IEEE802154_DEBUG is not set # CONFIG_IEEE802154_DEBUG_ASSERT_MONITOR is not set # end of IEEE 802.15.4 @@ -2696,6 +2709,8 @@ 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 CONFIG_ESP32_PHY_MAX_TX_POWER=20 +CONFIG_MAC_BB_PD=y +CONFIG_ESP32_PHY_MAC_BB_PD=y # CONFIG_REDUCE_PHY_TX_POWER is not set # CONFIG_ESP32_REDUCE_PHY_TX_POWER is not set CONFIG_ESP_SYSTEM_PM_POWER_DOWN_CPU=y diff --git a/sdkconfig.seeed_xiao_esp32c6.old b/sdkconfig.seeed_xiao_esp32c6.old index 2c01ff3..1b384f0 100644 --- a/sdkconfig.seeed_xiao_esp32c6.old +++ b/sdkconfig.seeed_xiao_esp32c6.old @@ -1,7 +1,3 @@ -# -# Automatically generated file. DO NOT EDIT. -# Espressif IoT Development Framework (ESP-IDF) 5.5.1 Project Configuration -# CONFIG_SOC_ADC_SUPPORTED=y CONFIG_SOC_DEDICATED_GPIO_SUPPORTED=y CONFIG_SOC_UART_SUPPORTED=y @@ -1153,7 +1149,6 @@ CONFIG_ESP_TLS_DYN_BUF_STRATEGY_SUPPORTED=y CONFIG_ESP_COEX_ENABLED=y CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y # CONFIG_ESP_COEX_POWER_MANAGEMENT is not set -# CONFIG_ESP_COEX_GPIO_DEBUG is not set # end of Wireless Coexistence # @@ -1294,6 +1289,7 @@ CONFIG_SPI_SLAVE_ISR_IN_IRAM=y # ESP-Driver:USB Serial/JTAG Configuration # CONFIG_USJ_ENABLE_USB_SERIAL_JTAG=y +# CONFIG_USJ_NO_AUTO_LS_ON_CONNECTION is not set # end of ESP-Driver:USB Serial/JTAG Configuration # @@ -1424,6 +1420,7 @@ CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=0 # CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set # CONFIG_ESP_SLEEP_DEBUG is not set CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y +# CONFIG_ESP_SLEEP_EVENT_CALLBACKS is not set # end of Sleep Config # @@ -1528,6 +1525,7 @@ CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y # CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 CONFIG_ESP_PHY_MAX_TX_POWER=20 +# CONFIG_ESP_PHY_MAC_BB_PD is not set # CONFIG_ESP_PHY_REDUCE_TX_POWER is not set # CONFIG_ESP_PHY_ENABLE_CERT_TEST is not set CONFIG_ESP_PHY_RF_CAL_PARTIAL=y @@ -1545,11 +1543,18 @@ CONFIG_ESP_PHY_IRAM_OPT=y # Power Management # CONFIG_PM_SLEEP_FUNC_IN_IRAM=y -# CONFIG_PM_ENABLE is not set +CONFIG_PM_ENABLE=y +CONFIG_PM_DFS_INIT_AUTO=y +# CONFIG_PM_PROFILING is not set +CONFIG_PM_TRACE=y CONFIG_PM_SLP_IRAM_OPT=y +CONFIG_PM_RTOS_IDLE_OPT=y +CONFIG_PM_SLP_DISABLE_GPIO=y CONFIG_PM_SLP_DEFAULT_PARAMS_OPT=y +CONFIG_PM_LIGHTSLEEP_RTC_OSC_CAL_INTERVAL=1 CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP=y -# CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP is not set +CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y +# CONFIG_PM_LIGHT_SLEEP_CALLBACKS is not set # end of Power Management # @@ -1664,7 +1669,7 @@ CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y -# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set +CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD=y CONFIG_ESP_TIMER_IMPL_SYSTIMER=y # end of ESP Timer (High Resolution Timer) @@ -1830,6 +1835,8 @@ CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 # CONFIG_FREERTOS_USE_TRACE_FACILITY is not set # CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES is not set # CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +CONFIG_FREERTOS_USE_TICKLESS_IDLE=y +CONFIG_FREERTOS_IDLE_TIME_BEFORE_SLEEP=3 # CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set # end of Kernel @@ -1909,6 +1916,7 @@ CONFIG_IEEE802154_CCA_THRESHOLD=-60 CONFIG_IEEE802154_PENDING_TABLE_SIZE=20 # CONFIG_IEEE802154_MULTI_PAN_ENABLE is not set CONFIG_IEEE802154_TIMING_OPTIMIZATION=y +# CONFIG_IEEE802154_SLEEP_ENABLE is not set # CONFIG_IEEE802154_DEBUG is not set # CONFIG_IEEE802154_DEBUG_ASSERT_MONITOR is not set # end of IEEE 802.15.4 diff --git a/src/main.cpp b/src/main.cpp index a1aafe4..5bd2bb7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,6 +8,7 @@ #include "socketIO.hpp" #include "encoder.hpp" #include "calibration.hpp" +#include "esp_pm.h" // Global encoder instances Encoder* topEnc = new Encoder(ENCODER_PIN_A, ENCODER_PIN_B); @@ -35,62 +36,53 @@ void mainApp() { bottomEnc->init(); servoInit(); - setupLoop(); + xTaskCreate(setupLoop, "Setup", 8192, NULL, 5, &setupTaskHandle); - statusResolved = false; - - int32_t prevCount = topEnc->getCount(); + // TOMORROW!!! + // statusResolved = false; - // Main loop - while (1) { - // websocket disconnect/reconnect handling - if (statusResolved) { - if (!connected) { - printf("Disconnected! Beginning setup loop.\n"); - stopSocketIO(); - setupLoop(); - } - else printf("Reconnected!\n"); - statusResolved = false; - } + // // Main loop + // while (1) { + // // websocket disconnect/reconnect handling + // if (statusResolved) { + // if (!connected) { + // printf("Disconnected! Beginning setup loop.\n"); + // stopSocketIO(); + // setupLoop(); + // } + // else printf("Reconnected!\n"); + // statusResolved = false; + // } - if (clearCalibFlag) { - calib.clearCalibrated(); - emitCalibStatus(false); - clearCalibFlag = false; - } - if (savePosFlag) { - servoSavePos(); - savePosFlag = false; + // if (clearCalibFlag) { + // calib.clearCalibrated(); + // emitCalibStatus(false); + // clearCalibFlag = false; + // } + // if (savePosFlag) { + // servoSavePos(); + // savePosFlag = false; - // Send position update to server - uint8_t currentAppPos = calib.convertToAppPos(topEnc->getCount()); - emitPosHit(currentAppPos); + // // Send position update to server + // uint8_t currentAppPos = calib.convertToAppPos(topEnc->getCount()); + // emitPosHit(currentAppPos); - printf("Sent pos_hit: position %d\n", currentAppPos); - } - vTaskDelay(pdMS_TO_TICKS(100)); - } + // printf("Sent pos_hit: position %d\n", currentAppPos); + // } + // vTaskDelay(pdMS_TO_TICKS(100)); + // } } -void encoderTest() { - // Create encoder instance - Encoder encoder(ENCODER_PIN_A, ENCODER_PIN_B); - encoder.init(); - - int32_t prevCount = encoder.getCount(); - - while (1) { - int32_t currentCount = encoder.getCount(); - if (currentCount != prevCount) { - prevCount = currentCount; - printf("Encoder Pos: %d\n", prevCount); - } - vTaskDelay(pdMS_TO_TICKS(100)); - } +void pm_init() { + esp_pm_config_t pm_config = { + .max_freq_mhz = 160, // Max CPU frequency + .min_freq_mhz = 80, // Min CPU frequency (DFS) + .light_sleep_enable = true // ALLOW CPU to power down during idle + }; + ESP_ERROR_CHECK(esp_pm_configure(&pm_config)); } extern "C" void app_main() { + pm_init(); mainApp(); - // encoderTest(); } \ No newline at end of file