diff --git a/ADIS_ESP32_Eclipse/main/CMakeLists.txt b/ADIS_ESP32_Eclipse/main/CMakeLists.txt index dff554d..8c9f0dc 100644 --- a/ADIS_ESP32_Eclipse/main/CMakeLists.txt +++ b/ADIS_ESP32_Eclipse/main/CMakeLists.txt @@ -20,6 +20,7 @@ idf_component_register( "challenge_app.c" "splitflap_wrapper.c" "challenge_com.c" + "challenge_nvs.c" INCLUDE_DIRS "." diff --git a/ADIS_ESP32_Eclipse/main/challenge_app.c b/ADIS_ESP32_Eclipse/main/challenge_app.c index 4edc7c1..9f00fa0 100644 --- a/ADIS_ESP32_Eclipse/main/challenge_app.c +++ b/ADIS_ESP32_Eclipse/main/challenge_app.c @@ -16,9 +16,8 @@ #include "wifi.h" #include "McuUtility.h" #include "challenge_com.h" -#include "esp_system.h" -#include "nvs_flash.h" -#include "nvs.h" +#include "challenge_nvs.h" + /* LOCAL Var */ /* identifies robot Mode for the challenge: true = robot is stationary, false = robot is moveable */ @@ -27,10 +26,8 @@ static bool _robotModeStationary = false; static TaskHandle_t appTaskHandle; /* task handle */ #define TAG "CHALLENGE_APP" /* tag for logging with ESP_LOG */ -/* function declarations */ +/* local function declarations */ static void Challenge_App_SetRobotMode(bool modeStationary, bool storeToNvs); -static bool Challenge_App_StoreRobotModeToNVS(bool modeStationary); -static bool Challenge_App_GetRobotModeFromNVS(void); static void appTask(void *pv){ @@ -77,17 +74,9 @@ static void appTask(void *pv){ BaseType_t res; void Challenge_App_Init(void){ - // Initialize NVS - esp_err_t err = nvs_flash_init(); - if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) { - // NVS partition was truncated and needs to be erased - // Retry nvs_flash_init - ESP_ERROR_CHECK(nvs_flash_erase()); - err = nvs_flash_init(); - } - ESP_ERROR_CHECK( err ); + Challenge_Nvs_Init(); - Challenge_App_GetRobotModeFromNVS(); + Challenge_Nvs_GetRobotModeFromNVS(&_robotModeStationary); res = xTaskCreate(appTask, "ChallengeAppTask", 4096/sizeof(StackType_t), (void*)"ARG_0", tskIDLE_PRIORITY, &appTaskHandle); if(res != pdPASS){ @@ -103,96 +92,10 @@ static void Challenge_App_SetRobotMode(bool modeStationary, bool storeToNvs){ _robotModeStationary = modeStationary; ESP_LOGI(TAG, "Changed robot mode to %s", _robotModeStationary?(unsigned char*)"stationary":(unsigned char*)"mobile"); if(storeToNvs){ - Challenge_App_StoreRobotModeToNVS(modeStationary); - } -} - -// returns true on success -static bool Challenge_App_StoreRobotModeToNVS(bool modeStationary){ - bool success = false; - - // Open - ESP_LOGI(TAG, "Opening Non-Volatile Storage (NVS) handle... "); - nvs_handle_t my_handle; - esp_err_t err = nvs_open("storage", NVS_READWRITE, &my_handle); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Error (%s) opening NVS handle!\n", esp_err_to_name(err)); - return false; - } - - // Write - uint8_t value = modeStationary==true?1:0; - ESP_LOGI(TAG, "Updating robotMode in NVS ... "); - err = nvs_set_u8(my_handle, "robotMode", value); - if(err != ESP_OK){ - ESP_LOGE(TAG, "Failed to update robotMode in NVS. Error=(%s)", esp_err_to_name(err)); - success = false; - }else{ // successfully set - // Commit written value. - // After setting any values, nvs_commit() must be called to ensure changes are written - // to flash storage. Implementations may write to storage at other times, - // but this is not guaranteed. - ESP_LOGI(TAG, "Committing updates in NVS ... "); - err = nvs_commit(my_handle); - if(err != ESP_OK){ - ESP_LOGE(TAG, "Failed to commit to NVS. Error=(%s)", esp_err_to_name(err)); - success = false; - }else{ - ESP_LOGI(TAG, "Successfully committed changes to NVS."); - success = true; - } - } - - // Close - nvs_close(my_handle); - - return success; -} - -// returns true on success -static bool Challenge_App_GetRobotModeFromNVS(void){ - bool success = false; - bool notInitialized = false; - - // Open - ESP_LOGI(TAG, "Opening Non-Volatile Storage (NVS) handle... "); - nvs_handle_t my_handle; - esp_err_t err = nvs_open("storage", NVS_READWRITE, &my_handle); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Error (%s) opening NVS handle!\n", esp_err_to_name(err)); - return false; - } - - // Read - ESP_LOGI(TAG, "Reading robot mode from NVS ... "); - uint8_t value = 0; - err = nvs_get_u8(my_handle, "robotMode", &value); - switch (err) { - case ESP_OK: - ESP_LOGI(TAG, "Reading robot mode done. Read robotMode = %i", value); - Challenge_App_SetRobotMode(value==1?true:false, false); // do not store to nvs (reading rn) - success = true; - break; - case ESP_ERR_NVS_NOT_FOUND: - ESP_LOGI(TAG, "Reading robot mode done. The value is not initialized yet!"); - notInitialized = true; - break; - default : - ESP_LOGI(TAG, "Error reading robot mode. Error=(%s)", esp_err_to_name(err)); - success = false; + Challenge_Nvs_StoreRobotModeToNVS(modeStationary); } - - // Close - nvs_close(my_handle); - - if(notInitialized){ - success = Challenge_App_StoreRobotModeToNVS(false); // initialize to false - } - - return success; } - /*********/ /* SHELL */ /*********/ diff --git a/ADIS_ESP32_Eclipse/main/challenge_nvs.c b/ADIS_ESP32_Eclipse/main/challenge_nvs.c new file mode 100644 index 0000000..fc7f6c3 --- /dev/null +++ b/ADIS_ESP32_Eclipse/main/challenge_nvs.c @@ -0,0 +1,138 @@ +/* + * challenge_nvs.c + * + * Created on: 08.12.2022 + * Author: jonas + */ + +#include "challenge_nvs.h" +#include "esp_log.h" +#include "esp_system.h" +#include "nvs_flash.h" +#include "nvs.h" + +/* defines / constants */ +#define TAG "CHALLENGE_NVS" /* tag for logging with ESP_LOG */ +const char* NAMESPACE_NVS = "storage"; +const char* ROBOT_MODE_KEY = "robot_mode"; + +/* local vars */ +bool initializedSuccessfully = false; + +/*! \brief Initialize the NVS storage. */ +void Challenge_Nvs_Init(void){ + ESP_LOGI(TAG, "Initializing..."); + + // Initialize NVS + esp_err_t err = nvs_flash_init(); + if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) { + // NVS partition was truncated and needs to be erased + // Retry nvs_flash_init + ESP_ERROR_CHECK(nvs_flash_erase()); + err = nvs_flash_init(); + } + ESP_ERROR_CHECK( err ); + initializedSuccessfully = (err == ESP_OK); + + ESP_LOGI(TAG, "Initialized. Success=%s", initializedSuccessfully?"true":"false"); +} + +/*! \brief Deinitialize the NVS storage. */ +void Challenge_Nvs_Deinit(void){ + ESP_LOGI(TAG, "Deinitializing..."); + esp_err_t err = nvs_flash_deinit(); + ESP_LOGI(TAG, "Deinitialized. Success=%s", err==ESP_OK?"true":"false"); +} + +/*! +* \brief Stores the passed robot mode in NVS. +* \param modeStationary Mode to store. True = stationary mode, False = mobile mode +* \return true on success +*/ +bool Challenge_Nvs_StoreRobotModeToNVS(bool mode){ + bool success = false; + + // Open + ESP_LOGI(TAG, "Opening Non-Volatile Storage (NVS) handle... "); + nvs_handle_t my_handle; + esp_err_t err = nvs_open(NAMESPACE_NVS, NVS_READWRITE, &my_handle); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Error (%s) opening NVS handle!\n", esp_err_to_name(err)); + return false; + } + + // Write + uint8_t value = mode?1:0; + ESP_LOGI(TAG, "Updating robotMode in NVS ... "); + err = nvs_set_u8(my_handle, ROBOT_MODE_KEY, value); + if(err != ESP_OK){ + ESP_LOGE(TAG, "Failed to update robotMode in NVS. Error=(%s)", esp_err_to_name(err)); + success = false; + }else{ // successfully set + // Commit written value. + // After setting any values, nvs_commit() must be called to ensure changes are written + // to flash storage. Implementations may write to storage at other times, + // but this is not guaranteed. + ESP_LOGI(TAG, "Committing updates in NVS ... "); + err = nvs_commit(my_handle); + if(err != ESP_OK){ + ESP_LOGE(TAG, "Failed to commit to NVS. Error=(%s)", esp_err_to_name(err)); + success = false; + }else{ + ESP_LOGI(TAG, "Successfully committed changes to NVS."); + success = true; + } + } + + // Close + nvs_close(my_handle); + + return success; +} + +/*! + * \brief Retrieve the robot mode stored in NVS. + * \param mode Pointer to the location where to retrieve the mode to. True = stationary mode, False = mobile mode + * \return true on success + */ +bool Challenge_Nvs_GetRobotModeFromNVS(bool *mode){ + bool success = false; + bool notInitialized = false; + + // Open + ESP_LOGI(TAG, "Opening Non-Volatile Storage (NVS) handle... "); + nvs_handle_t my_handle; + esp_err_t err = nvs_open(NAMESPACE_NVS, NVS_READWRITE, &my_handle); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Error (%s) opening NVS handle!\n", esp_err_to_name(err)); + return false; + } + + // Read + ESP_LOGI(TAG, "Reading robot mode from NVS ... "); + uint8_t value = 0; + err = nvs_get_u8(my_handle, ROBOT_MODE_KEY, &value); + switch (err) { + case ESP_OK: + ESP_LOGI(TAG, "Reading robot mode done. Read robotMode = %i", value); + *mode = (bool)(value==1?true:false); // set value at pointer location + success = true; + break; + case ESP_ERR_NVS_NOT_FOUND: + ESP_LOGI(TAG, "Reading robot mode done. The value is not initialized yet!"); + notInitialized = true; + break; + default : + ESP_LOGI(TAG, "Error reading robot mode. Error=(%s)", esp_err_to_name(err)); + success = false; + } + + // Close + nvs_close(my_handle); + + if(notInitialized){ + success = Challenge_Nvs_StoreRobotModeToNVS(false); // initialize to false + } + + return success; +} diff --git a/ADIS_ESP32_Eclipse/main/challenge_nvs.h b/ADIS_ESP32_Eclipse/main/challenge_nvs.h new file mode 100644 index 0000000..e1655be --- /dev/null +++ b/ADIS_ESP32_Eclipse/main/challenge_nvs.h @@ -0,0 +1,33 @@ +/* + * challenge_nvs.h + * + * Created on: 08.12.2022 + * Author: jonas + */ + +#ifndef MAIN_CHALLENGE_NVS_H_ +#define MAIN_CHALLENGE_NVS_H_ + +#include + +/*! \brief Initialize the NVS storage. */ +void Challenge_Nvs_Init(void); + +/*! \brief Deinitialize the NVS storage. */ +void Challenge_Nvs_Deinit(void); + +/*! +* \brief Stores the passed robot mode in NVS. +* \param modeStationary Mode to store. True = stationary mode, False = mobile mode +* \return true on success +*/ +bool Challenge_Nvs_StoreRobotModeToNVS(bool mode); + +/*! + * \brief Retrieve the robot mode stored in NVS. If the robot mode is not yet stored in NVS, it will be initially stored as false. + * \param mode Pointer to the location where to retrieve the mode to. True = stationary mode, False = mobile mode + * \return true on success + */ +bool Challenge_Nvs_GetRobotModeFromNVS(bool *mode); + +#endif /* MAIN_CHALLENGE_NVS_H_ */