Merge pull request 'feat(nvs): Add NVS support for relay channel persistence (#1074)' (!33) from feat/1074-add-nvs-storage into dev

Reviewed-on: #33
This commit was merged in pull request #33.
This commit is contained in:
2025-08-19 18:55:11 +03:00
34 changed files with 993 additions and 265 deletions

2
.gitignore vendored
View File

@@ -68,7 +68,7 @@ coverage_report/
test_multi_heap_host test_multi_heap_host
# VS Code Settings # VS Code Settings
.vscode/ # .vscode/
# VIM files # VIM files
*.swp *.swp

23
.vscode/c_cpp_properties.json vendored Normal file
View File

@@ -0,0 +1,23 @@
{
"configurations": [
{
"name": "ESP-IDF",
"compilerPath": "${config:idf.toolsPath}/tools/riscv32-esp-elf/esp-14.2.0_20241119/riscv32-esp-elf/bin/riscv32-esp-elf-gcc",
"compileCommands": "${config:idf.buildPath}/compile_commands.json",
"includePath": [
"${config:idf.espIdfPath}/components/**",
"${config:idf.espIdfPathWin}/components/**",
"${workspaceFolder}/**"
],
"browse": {
"path": [
"${config:idf.espIdfPath}/components",
"${config:idf.espIdfPathWin}/components",
"${workspaceFolder}"
],
"limitSymbolsToIncludedHeaders": true
}
}
],
"version": 4
}

15
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,15 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "gdbtarget",
"request": "attach",
"name": "Eclipse CDT GDB Adapter"
},
{
"type": "espidf",
"name": "Launch",
"request": "launch"
}
]
}

22
.vscode/settings.json vendored
View File

@@ -1,23 +1,3 @@
{ {
"files.associations": { "C_Cpp.intelliSenseEngine": "default"
"relay_chn.h": "c",
"stdlib.h": "c",
"cstdint": "c",
"relay_chn_run_info.h": "c",
"esp_err.h": "c",
"relay_chn_output.h": "c",
"relay_chn_core.h": "c",
"relay_chn_ctl.h": "c",
"relay_chn_tilt.h": "c",
"relay_chn_defs.h": "c",
"esp_check.h": "c",
"esp_event_base.h": "c",
"esp_event.h": "c",
"queue.h": "c",
"relay_chn_priv_types.h": "c",
"relay_chn_adapter.h": "c",
"relay_chn_types.h": "c"
},
"idf.port": "/dev/ttyUSB0",
"idf.pythonInstallPath": "/usr/bin/python"
} }

View File

@@ -15,7 +15,12 @@ else()
list(APPEND srcs "src/relay_chn_ctl_single.c") list(APPEND srcs "src/relay_chn_ctl_single.c")
endif() endif()
if(CONFIG_RELAY_CHN_NVS)
list(APPEND srcs "src/relay_chn_nvs.c")
endif()
idf_component_register(SRCS ${srcs} idf_component_register(SRCS ${srcs}
INCLUDE_DIRS ${include_dirs} INCLUDE_DIRS ${include_dirs}
PRIV_INCLUDE_DIRS ${priv_include_dirs} PRIV_INCLUDE_DIRS ${priv_include_dirs}
REQUIRES driver esp_timer esp_event) REQUIRES driver esp_timer esp_event nvs_flash)

35
Kconfig
View File

@@ -26,4 +26,39 @@ menu "Relay Channel Driver Configuration"
at a time. Tilting is specifically designed for controlling some at a time. Tilting is specifically designed for controlling some
types of curtains that need to be adjusted to let enter specific types of curtains that need to be adjusted to let enter specific
amount of day light. amount of day light.
config RELAY_CHN_ENABLE_NVS
bool "Enable persistent NVS storage for relay channel"
default n
help
If enabled, relay channel configuration will be stored in NVS.
endmenu
menu "Relay Channel NVS Storage Configuration"
depends on RELAY_CHN_ENABLE_NVS
config RELAY_CHN_NVS_NAMESPACE
string "NVS namespace for relay channel storage"
default "relay_chn"
help
The NVS namespace used for storing relay channel configuration.
This should be unique to avoid conflicts with other components.
config RELAY_CHN_NVS_CUSTOM_PARTITION
bool "Use custom NVS partition for relay channel storage"
default n
help
If enabled, a custom NVS partition will be used for storing
relay channel configuration. If disabled, the default NVS
partition will be used.
config RELAY_CHN_NVS_CUSTOM_PARTITION_NAME
string "Custom NVS partition name"
depends on RELAY_CHN_NVS_CUSTOM_PARTITION
default "app_data"
help
The name of the custom NVS partition used for storing relay channel
configuration. Make sure the name is exactly the same as label defined
in the relevant partition table.
endmenu endmenu

View File

@@ -14,6 +14,15 @@ extern "C" {
#define RELAY_CHN_OPPOSITE_INERTIA_MS CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS #define RELAY_CHN_OPPOSITE_INERTIA_MS CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS
#define RELAY_CHN_COUNT CONFIG_RELAY_CHN_COUNT #define RELAY_CHN_COUNT CONFIG_RELAY_CHN_COUNT
#define RELAY_CHN_ENABLE_TILTING CONFIG_RELAY_CHN_ENABLE_TILTING #define RELAY_CHN_ENABLE_TILTING CONFIG_RELAY_CHN_ENABLE_TILTING
#define RELAY_CHN_ENABLE_NVS CONFIG_RELAY_CHN_ENABLE_NVS
#if RELAY_CHN_ENABLE_NVS == 1
#define RELAY_CHN_NVS_NAMESPACE CONFIG_RELAY_CHN_NVS_NAMESPACE
#define RELAY_CHN_NVS_CUSTOM_PARTITION CONFIG_RELAY_CHN_NVS_CUSTOM_PARTITION
#if RELAY_CHN_NVS_CUSTOM_PARTITION == 1
#define RELAY_CHN_NVS_CUSTOM_PARTITION_NAME CONFIG_RELAY_CHN_NVS_CUSTOM_PARTITION_NAME
#endif
#endif
#if RELAY_CHN_COUNT > 1 #if RELAY_CHN_COUNT > 1
#define RELAY_CHN_ID_ALL RELAY_CHN_COUNT /*!< Special ID to address all channels */ #define RELAY_CHN_ID_ALL RELAY_CHN_COUNT /*!< Special ID to address all channels */

View File

@@ -0,0 +1,106 @@
/*
* SPDX-FileCopyrightText: 2025 Kozmotronik Tech
*
* SPDX-License-Identifier: MIT
*/
#pragma once
#include <stdint.h>
#include "esp_err.h"
#include "nvs_flash.h"
#include "nvs.h"
#include "relay_chn_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initialize NVS storage for relay channels.
*
* @attention Before calling this function, make sure the NVS flash is initialised
* using either the nvs_flash_init() function for the default NVS partition or the
* nvs_flash_init_partition() function for a custom partition.
*
* @return ESP_OK on success, error code otherwise.
*/
esp_err_t relay_chn_nvs_init(void);
/**
* @brief Store relay channel direction in NVS.
*
* @param[in] ch Channel number.
* @param[in] direction Direction to store.
* @return ESP_OK on success, error code otherwise.
*/
esp_err_t relay_chn_nvs_set_direction(uint8_t ch, relay_chn_direction_t direction);
/**
* @brief Retrieve relay channel direction from NVS.
*
* @param[in] ch Channel number.
* @param[out] direction Pointer to store retrieved direction.
* @return ESP_OK on success, error code otherwise.
*/
esp_err_t relay_chn_nvs_get_direction(uint8_t ch, relay_chn_direction_t *direction);
#ifdef RELAY_CHN_ENABLE_TILTING
/**
* @brief Store tilt sensitivity in NVS.
*
* @param[in] ch Channel number.
* @param[in] sensitivity Sensitivity value to store.
* @return ESP_OK on success, error code otherwise.
*/
esp_err_t relay_chn_nvs_set_tilt_sensitivity(uint8_t ch, uint8_t sensitivity);
/**
* @brief Retrieve tilt sensitivity from NVS.
*
* @param[in] ch Channel number.
* @param[out] sensitivity Pointer to store retrieved sensitivity.
* @return ESP_OK on success, error code otherwise.
*/
esp_err_t relay_chn_nvs_get_tilt_sensitivity(uint8_t ch, uint8_t *sensitivity);
/**
* @brief Store tilt counters in NVS.
*
* @param[in] ch Channel number.
* @param[in] forward_count Forward tilt counter value.
* @param[in] reverse_count Reverse tilt counter value.
* @return ESP_OK on success, error code otherwise.
*/
esp_err_t relay_chn_nvs_set_tilt_count(uint8_t ch, uint32_t forward_count, uint32_t reverse_count);
/**
* @brief Retrieve tilt counters from NVS.
*
* @param[in] ch Channel number.
* @param[out] forward_count Pointer to store forward tilt counter.
* @param[out] reverse_count Pointer to store reverse tilt counter.
* @return ESP_OK on success, error code otherwise.
*/
esp_err_t relay_chn_nvs_get_tilt_count(uint8_t ch, uint32_t *forward_count, uint32_t *reverse_count);
#endif // RELAY_CHN_ENABLE_TILTING
/**
* @brief Erase all keys in the NVS namespace.
*
* This function will erase all key-value pairs in the NVS namespace used by relay channels.
*
* @return ESP_OK on success, error code otherwise.
*/
esp_err_t relay_chn_nvs_erase_all(void);
/**
* @brief Deinitialize NVS storage for relay channels.
*
* @return ESP_OK on success, error code otherwise.
*/
esp_err_t relay_chn_nvs_deinit(void);
#ifdef __cplusplus
}
#endif

View File

@@ -10,7 +10,7 @@ if [[ -z "$IDF_PATH" ]]; then
fi fi
# ==== 2. Valid Modes and Defaults ==== # ==== 2. Valid Modes and Defaults ====
valid_test_tags=("core" "tilt" "listener" "all" "relay_chn") valid_test_tags=("core" "tilt" "listener" "all" "relay_chn" "nvs")
arg_tag="all" # Default to 'all' if no tag specified arg_tag="all" # Default to 'all' if no tag specified
arg_clean=false arg_clean=false
arg_log=false arg_log=false
@@ -24,7 +24,7 @@ print_help() {
echo "This script builds and runs tests for the relay_chn component using QEMU." echo "This script builds and runs tests for the relay_chn component using QEMU."
echo "" echo ""
echo "Arguments:" echo "Arguments:"
echo " -t, --tag [relay_chn|core|tilt|listener|all] Specify which test tag to run." echo " -t, --tag [relay_chn|core|tilt|listener|nvs|all] Specify which test tag to run."
echo "" echo ""
echo " If no tag is specified, it defaults to 'all'." echo " If no tag is specified, it defaults to 'all'."
echo "" echo ""

30
scripts/run_tests_all_cfgs.sh Executable file
View File

@@ -0,0 +1,30 @@
#!/usr/bin/env bash
set -e
# Check tag argument
arg_tag=$1
if [[ -z "$arg_tag" ]]; then
arg_tag="all"
fi
# Resolve Paths and Switch to Working Directory
script_dir=$(dirname "$(readlink -f "$0")")
project_root=$(dirname "$script_dir")
echo "Script dir: ${script_dir}"
echo "Project root: ${project_root}"
echo "🔍 Searching for 'test_apps' directory in '$project_root'..."
test_apps_dir=$(find "$project_root" -type d -name "test_apps" | head -n 1)
echo "test_apps dir: ${test_apps_dir}"
# Execute tests for all configs
mapfile -t sdkcfg_files < <(find "$test_apps_dir" -maxdepth 1 -type f -name "sdkconfig.defaults*")
for sdkcfg_file in "${sdkcfg_files[@]}"; do
echo "🔧 Running tests with config: $sdkcfg_file"
"${script_dir}"/run_tests.sh -c -f "$sdkcfg_file" -t "$arg_tag" || {
echo "❌ Tests failed with config: $sdkcfg_file"
exit 1
}
done

View File

@@ -11,9 +11,15 @@
#include "relay_chn_output.h" #include "relay_chn_output.h"
#include "relay_chn_run_info.h" #include "relay_chn_run_info.h"
#include "relay_chn_ctl.h" #include "relay_chn_ctl.h"
#if RELAY_CHN_ENABLE_TILTING == 1 #if RELAY_CHN_ENABLE_TILTING == 1
#include "relay_chn_tilt.h" #include "relay_chn_tilt.h"
#endif #endif
#if RELAY_CHN_ENABLE_NVS == 1
#include "relay_chn_nvs.h"
#endif
#include "relay_chn_core.h" #include "relay_chn_core.h"
@@ -89,6 +95,11 @@ esp_err_t relay_chn_create(const uint8_t* gpio_map, uint8_t gpio_count)
ESP_RETURN_ON_FALSE(gpio_map != NULL, ESP_ERR_INVALID_ARG, TAG, "gpio_map cannot be NULL"); ESP_RETURN_ON_FALSE(gpio_map != NULL, ESP_ERR_INVALID_ARG, TAG, "gpio_map cannot be NULL");
esp_err_t ret; esp_err_t ret;
#if RELAY_CHN_ENABLE_NVS == 1
ret = relay_chn_nvs_init();
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to initialize NVS for relay channel");
#endif
// Initialize the output // Initialize the output
ret = relay_chn_output_init(gpio_map, gpio_count); ret = relay_chn_output_init(gpio_map, gpio_count);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to initialize relay channel outputs"); ESP_RETURN_ON_ERROR(ret, TAG, "Failed to initialize relay channel outputs");
@@ -137,6 +148,10 @@ void relay_chn_destroy(void)
relay_chn_ctl_deinit(); relay_chn_ctl_deinit();
relay_chn_output_deinit(); relay_chn_output_deinit();
#if RELAY_CHN_ENABLE_NVS == 1
relay_chn_nvs_deinit();
#endif
// Destroy the event loop // Destroy the event loop
esp_event_loop_delete(relay_chn_event_loop); esp_event_loop_delete(relay_chn_event_loop);
relay_chn_event_loop = NULL; relay_chn_event_loop = NULL;

125
src/relay_chn_nvs.c Normal file
View File

@@ -0,0 +1,125 @@
/*
* SPDX-FileCopyrightText: 2025 Kozmotronik Tech
*
* SPDX-License-Identifier: MIT
*/
#include "esp_check.h"
#include "relay_chn_nvs.h"
#define RELAY_CHN_KEY_DIR "dir"
#ifdef RELAY_CHN_ENABLE_TILTING
#define RELAY_CHN_KEY_SENS(ch) "sens_%d"
#define RELAY_CHN_KEY_TFWD(ch) "tfwd_%d"
#define RELAY_CHN_KEY_TREV(ch) "trev_%d"
#endif
static const char *TAG = "RELAY_CHN_STORAGE_NVS";
static nvs_handle_t relay_chn_nvs;
esp_err_t relay_chn_nvs_init()
{
esp_err_t ret;
#if RELAY_CHN_NVS_CUSTOM_PARTITION == 1
ret = nvs_open_from_partition(RELAY_CHN_NVS_CUSTOM_PARTITION_NAME,
RELAY_CHN_NVS_NAMESPACE,
NVS_READWRITE,
&relay_chn_nvs);
ESP_RETURN_ON_ERROR(ret,
TAG,
"Failed to open NVS namespace '%s' from partition '%s' with error %s",
RELAY_CHN_NVS_NAMESPACE,
RELAY_CHN_NVS_CUSTOM_PARTITION_NAME,
esp_err_to_name(ret));
#else
ret = nvs_open(RELAY_CHN_NVS_NAMESPACE, NVS_READWRITE, &relay_chn_nvs);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to open NVS namespace '%s'", RELAY_CHN_NVS_NAMESPACE);
#endif // RELAY_CHN_NVS_CUSTOM_PARTITION
return ESP_OK;
}
esp_err_t relay_chn_nvs_set_direction(uint8_t ch, relay_chn_direction_t direction)
{
uint8_t direction_val;
esp_err_t ret = nvs_get_u8(relay_chn_nvs, RELAY_CHN_KEY_DIR, &direction_val);
if (ret == ESP_ERR_NVS_NOT_FOUND) {
// The key does not exist yet, set it to zero which is the default direction
direction_val = RELAY_CHN_DIRECTION_DEFAULT;
} else if (ret != ESP_OK) {
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to get direction from NVS with error: %s", esp_err_to_name(ret));
}
direction_val &= ~(1 << ch); // Clear the bit for the channel
direction_val |= (((uint8_t) direction) << ch); // Set the new direction bit
ret = nvs_set_u8(relay_chn_nvs, RELAY_CHN_KEY_DIR, direction_val);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to set direction for channel %d", ch);
return nvs_commit(relay_chn_nvs);
}
esp_err_t relay_chn_nvs_get_direction(uint8_t ch, relay_chn_direction_t *direction)
{
ESP_RETURN_ON_FALSE(direction != NULL, ESP_ERR_INVALID_ARG, TAG, "Direction pointer is NULL");
uint8_t direction_val;
esp_err_t ret = nvs_get_u8(relay_chn_nvs, RELAY_CHN_KEY_DIR, &direction_val);
if (ret != ESP_OK) {
return ret; // Return error if the key does not exist
}
*direction = (relay_chn_direction_t)((direction_val >> ch) & 0x01);
return ESP_OK;
}
#ifdef RELAY_CHN_ENABLE_TILTING
esp_err_t relay_chn_nvs_set_tilt_sensitivity(uint8_t ch, uint8_t sensitivity)
{
esp_err_t ret = nvs_set_u8(relay_chn_nvs, RELAY_CHN_KEY_SENS(ch), sensitivity);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to set tilt sensitivity for channel %d", ch);
return nvs_commit(relay_chn_nvs);
}
esp_err_t relay_chn_nvs_get_tilt_sensitivity(uint8_t ch, uint8_t *sensitivity)
{
ESP_RETURN_ON_FALSE(sensitivity != NULL, ESP_ERR_INVALID_ARG, TAG, "Sensitivity pointer is NULL");
return nvs_get_u8(relay_chn_nvs, RELAY_CHN_KEY_SENS(ch), sensitivity);
}
esp_err_t relay_chn_nvs_set_tilt_count(uint8_t ch, uint32_t forward_count, uint32_t reverse_count)
{
esp_err_t ret;
ret = nvs_set_u32(relay_chn_nvs, RELAY_CHN_KEY_TFWD(ch), forward_count);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to save forward_count tilt counter");
ret = nvs_set_u32(relay_chn_nvs, RELAY_CHN_KEY_TREV(ch), reverse_count);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to save reverse_count tilt counter");
return nvs_commit(relay_chn_nvs);
}
esp_err_t relay_chn_nvs_get_tilt_count(uint8_t ch, uint32_t *forward_count, uint32_t *reverse_count)
{
ESP_RETURN_ON_FALSE(forward_count != NULL && reverse_count != NULL,
ESP_ERR_INVALID_ARG, TAG, "Counter pointers are NULL");
esp_err_t ret = nvs_get_u32(relay_chn_nvs, RELAY_CHN_KEY_TFWD(ch), forward_count);
if (ret != ESP_OK) {
return ret; // Return error if the key does not exist
}
return nvs_get_u32(relay_chn_nvs, RELAY_CHN_KEY_TREV(ch), reverse_count);
}
#endif // RELAY_CHN_ENABLE_TILTING
esp_err_t relay_chn_nvs_erase_all()
{
// Erase all key-value pairs in the relay_chn NVS namespace
esp_err_t ret = nvs_erase_all(relay_chn_nvs);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to erase all keys in NVS namespace '%s'", RELAY_CHN_NVS_NAMESPACE);
// Commit the changes
return nvs_commit(relay_chn_nvs);
}
esp_err_t relay_chn_nvs_deinit()
{
nvs_close(relay_chn_nvs);
return ESP_OK;
}

View File

@@ -10,6 +10,10 @@
#include "relay_chn_output.h" #include "relay_chn_output.h"
#include "relay_chn_core.h" #include "relay_chn_core.h"
#if RELAY_CHN_ENABLE_NVS == 1
#include "relay_chn_nvs.h"
#endif
static const char *TAG = "RELAY_CHN_OUTPUT"; static const char *TAG = "RELAY_CHN_OUTPUT";
@@ -38,7 +42,10 @@ static esp_err_t relay_chn_output_check_gpio_capabilities(uint8_t gpio_count)
return ESP_OK; return ESP_OK;
} }
static esp_err_t relay_chn_output_ctl_init(relay_chn_output_t *output, gpio_num_t forward_pin, gpio_num_t reverse_pin) static esp_err_t relay_chn_output_ctl_init(relay_chn_output_t *output,
gpio_num_t forward_pin,
gpio_num_t reverse_pin,
relay_chn_direction_t direction)
{ {
ESP_RETURN_ON_FALSE(GPIO_IS_VALID_OUTPUT_GPIO(forward_pin), ESP_ERR_INVALID_ARG, TAG, ESP_RETURN_ON_FALSE(GPIO_IS_VALID_OUTPUT_GPIO(forward_pin), ESP_ERR_INVALID_ARG, TAG,
"Invalid GPIO pin number for forward_pin: %d", forward_pin); "Invalid GPIO pin number for forward_pin: %d", forward_pin);
@@ -60,12 +67,26 @@ static esp_err_t relay_chn_output_ctl_init(relay_chn_output_t *output, gpio_num_
// Initialize the GPIOs // Initialize the GPIOs
// Initialize the relay channel output // Initialize the relay channel output
output->forward_pin = forward_pin; output->forward_pin = direction == RELAY_CHN_DIRECTION_DEFAULT ? forward_pin : reverse_pin;
output->reverse_pin = reverse_pin; output->reverse_pin = direction == RELAY_CHN_DIRECTION_DEFAULT ? reverse_pin : forward_pin;
output->direction = RELAY_CHN_DIRECTION_DEFAULT; output->direction = direction;
return ESP_OK; return ESP_OK;
} }
#if RELAY_CHN_ENABLE_NVS == 1
static esp_err_t relay_chn_output_load_direction(uint8_t ch, relay_chn_direction_t *direction)
{
esp_err_t ret = relay_chn_nvs_get_direction(ch, direction);
if (ret == ESP_ERR_NVS_NOT_FOUND) {
// If the key does not exist, use the default direction
*direction = RELAY_CHN_DIRECTION_DEFAULT;
} else if (ret != ESP_OK) {
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to get direction from storage for channel %d: %s", ch, esp_err_to_name(ret));
}
return ESP_OK;
}
#endif
esp_err_t relay_chn_output_init(const uint8_t* gpio_map, uint8_t gpio_count) esp_err_t relay_chn_output_init(const uint8_t* gpio_map, uint8_t gpio_count)
{ {
esp_err_t ret; esp_err_t ret;
@@ -79,11 +100,23 @@ esp_err_t relay_chn_output_init(const uint8_t* gpio_map, uint8_t gpio_count)
gpio_num_t forward_pin = (gpio_num_t) gpio_map[gpio_index]; gpio_num_t forward_pin = (gpio_num_t) gpio_map[gpio_index];
gpio_num_t reverse_pin = (gpio_num_t) gpio_map[gpio_index + 1]; gpio_num_t reverse_pin = (gpio_num_t) gpio_map[gpio_index + 1];
ret = relay_chn_output_ctl_init(output, forward_pin, reverse_pin); relay_chn_direction_t direction = RELAY_CHN_DIRECTION_DEFAULT;
#if RELAY_CHN_ENABLE_NVS == 1
// If NVS storage is enabled, retrieve the direction from storage
ret = relay_chn_output_load_direction(i, &direction);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to load direction from storage for channel %d", i);
#endif
ret = relay_chn_output_ctl_init(output, forward_pin, reverse_pin, direction);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to initialize relay channel %d", i); ESP_RETURN_ON_ERROR(ret, TAG, "Failed to initialize relay channel %d", i);
} }
#else #else
ret = relay_chn_output_ctl_init(&output, gpio_map[0], gpio_map[1]); relay_chn_direction_t direction = RELAY_CHN_DIRECTION_DEFAULT;
#if RELAY_CHN_ENABLE_NVS == 1
// If NVS storage is enabled, retrieve the direction from storage
ret = relay_chn_output_load_direction(0, &direction);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to load direction from storage for channel %d", 0);
#endif
ret = relay_chn_output_ctl_init(&output, gpio_map[0], gpio_map[1], direction);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to initialize relay channel"); ESP_RETURN_ON_ERROR(ret, TAG, "Failed to initialize relay channel");
#endif #endif
return ESP_OK; return ESP_OK;
@@ -160,6 +193,22 @@ void relay_chn_output_flip(relay_chn_output_t *output)
output->direction = (output->direction == RELAY_CHN_DIRECTION_DEFAULT) output->direction = (output->direction == RELAY_CHN_DIRECTION_DEFAULT)
? RELAY_CHN_DIRECTION_FLIPPED ? RELAY_CHN_DIRECTION_FLIPPED
: RELAY_CHN_DIRECTION_DEFAULT; : RELAY_CHN_DIRECTION_DEFAULT;
#if RELAY_CHN_ENABLE_NVS == 1
uint8_t ch = 0;
#if RELAY_CHN_COUNT > 1
for (uint8_t i = 0; i < RELAY_CHN_COUNT; i++) {
if (output == &outputs[i]) {
ch = i;
break;
}
}
#endif
esp_err_t ret = relay_chn_nvs_set_direction(ch, output->direction);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to save flipped direction for channel %d: %s", ch, esp_err_to_name(ret));
}
#endif
} }
relay_chn_direction_t relay_chn_output_get_direction(relay_chn_output_t *output) relay_chn_direction_t relay_chn_output_get_direction(relay_chn_output_t *output)

View File

@@ -10,6 +10,12 @@
#include "relay_chn_run_info.h" #include "relay_chn_run_info.h"
#include "relay_chn_tilt.h" #include "relay_chn_tilt.h"
#if RELAY_CHN_ENABLE_NVS == 1
#include "relay_chn_nvs.h"
#define RELAY_CHN_TILT_FLUSH_DEBOUNCE_MS 3000
#endif
static const char *TAG = "RELAY_CHN_TILT"; static const char *TAG = "RELAY_CHN_TILT";
@@ -65,6 +71,9 @@ typedef struct relay_chn_tilt_ctl {
relay_chn_tilt_timing_t tilt_timing; /*!< Tilt timing structure */ relay_chn_tilt_timing_t tilt_timing; /*!< Tilt timing structure */
relay_chn_tilt_counter_t tilt_counter; /*!< Tilt counter structure */ relay_chn_tilt_counter_t tilt_counter; /*!< Tilt counter structure */
esp_timer_handle_t tilt_timer; /*!< Tilt timer handle */ esp_timer_handle_t tilt_timer; /*!< Tilt timer handle */
#if RELAY_CHN_ENABLE_NVS == 1
esp_timer_handle_t flush_timer; /*!< Flush timer to avoid frequent write of tilt counters */
#endif
} relay_chn_tilt_ctl_t; } relay_chn_tilt_ctl_t;
@@ -295,7 +304,7 @@ static void relay_chn_tilt_set_timing_values(relay_chn_tilt_timing_t *tilt_timin
tilt_timing->pause_time_ms = pause_time_ms; tilt_timing->pause_time_ms = pause_time_ms;
} }
static void _relay_chn_tilt_sensitivity_set(relay_chn_tilt_ctl_t *tilt_ctl, uint8_t sensitivity) static void relay_chn_tilt_compute_set_sensitivity(relay_chn_tilt_ctl_t *tilt_ctl, uint8_t sensitivity)
{ {
if (sensitivity >= 100) { if (sensitivity >= 100) {
relay_chn_tilt_set_timing_values(&tilt_ctl->tilt_timing, relay_chn_tilt_set_timing_values(&tilt_ctl->tilt_timing,
@@ -309,6 +318,12 @@ static void _relay_chn_tilt_sensitivity_set(relay_chn_tilt_ctl_t *tilt_ctl, uint
RELAY_CHN_TILT_RUN_MIN_MS, RELAY_CHN_TILT_RUN_MIN_MS,
RELAY_CHN_TILT_PAUSE_MIN_MS); RELAY_CHN_TILT_PAUSE_MIN_MS);
} }
else if (sensitivity == RELAY_CHN_TILT_DEFAULT_SENSITIVITY) {
relay_chn_tilt_set_timing_values(&tilt_ctl->tilt_timing,
sensitivity,
RELAY_CHN_TILT_DEFAULT_RUN_MS,
RELAY_CHN_TILT_DEFAULT_PAUSE_MS);
}
else { else {
// Compute the new timing values from the sensitivity percent value by using linear interpolation // Compute the new timing values from the sensitivity percent value by using linear interpolation
uint32_t tilt_run_time_ms = 0, tilt_pause_time_ms = 0; uint32_t tilt_run_time_ms = 0, tilt_pause_time_ms = 0;
@@ -331,12 +346,16 @@ void relay_chn_tilt_set_sensitivity(uint8_t chn_id, uint8_t sensitivity)
if (chn_id == RELAY_CHN_ID_ALL) { if (chn_id == RELAY_CHN_ID_ALL) {
for (int i = 0; i < RELAY_CHN_COUNT; i++) { for (int i = 0; i < RELAY_CHN_COUNT; i++) {
_relay_chn_tilt_sensitivity_set(&tilt_ctls[i], sensitivity); relay_chn_tilt_compute_set_sensitivity(&tilt_ctls[i], sensitivity);
} }
} }
else { else {
_relay_chn_tilt_sensitivity_set(&tilt_ctls[chn_id], sensitivity); relay_chn_tilt_compute_set_sensitivity(&tilt_ctls[chn_id], sensitivity);
} }
#if RELAY_CHN_ENABLE_NVS == 1
relay_chn_nvs_set_tilt_sensitivity(chn_id, sensitivity);
#endif // RELAY_CHN_ENABLE_NVS
} }
esp_err_t relay_chn_tilt_get_sensitivity(uint8_t chn_id, uint8_t *sensitivity, size_t length) esp_err_t relay_chn_tilt_get_sensitivity(uint8_t chn_id, uint8_t *sensitivity, size_t length)
@@ -367,7 +386,11 @@ esp_err_t relay_chn_tilt_get_sensitivity(uint8_t chn_id, uint8_t *sensitivity, s
void relay_chn_tilt_set_sensitivity(uint8_t sensitivity) void relay_chn_tilt_set_sensitivity(uint8_t sensitivity)
{ {
_relay_chn_tilt_sensitivity_set(&tilt_ctl, sensitivity); relay_chn_tilt_compute_set_sensitivity(&tilt_ctl, sensitivity);
#if RELAY_CHN_ENABLE_NVS == 1
relay_chn_nvs_set_tilt_sensitivity(0, sensitivity);
#endif // RELAY_CHN_ENABLE_NVS
} }
uint8_t relay_chn_tilt_get_sensitivity() uint8_t relay_chn_tilt_get_sensitivity()
@@ -380,6 +403,10 @@ void relay_chn_tilt_reset_count(relay_chn_tilt_ctl_t *tilt_ctl)
{ {
tilt_ctl->tilt_counter.tilt_forward_count = 0; tilt_ctl->tilt_counter.tilt_forward_count = 0;
tilt_ctl->tilt_counter.tilt_reverse_count = 0; tilt_ctl->tilt_counter.tilt_reverse_count = 0;
#if RELAY_CHN_ENABLE_NVS == 1
esp_timer_stop(tilt_ctl->flush_timer);
#endif
} }
/** /**
@@ -449,6 +476,31 @@ static uint32_t relay_chn_tilt_count_update(relay_chn_tilt_ctl_t *tilt_ctl)
return 0; return 0;
} }
#if RELAY_CHN_ENABLE_NVS == 1
static esp_err_t relay_chn_tilt_save_tilt_counter(relay_chn_tilt_ctl_t *tilt_ctl)
{
// Save the tilt count to NVS storage
esp_err_t ret = relay_chn_nvs_set_tilt_count(tilt_ctl->chn_ctl->id,
tilt_ctl->tilt_counter.tilt_forward_count,
tilt_ctl->tilt_counter.tilt_reverse_count);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "relay_chn_tilt_execute_stop: Failed to save tilt count for channel #%d: %s", tilt_ctl->chn_ctl->id, esp_err_to_name(ret));
}
return ESP_OK;
}
static void relay_chn_tilt_flush_timer_cb(void *arg)
{
relay_chn_tilt_ctl_t* tilt_ctl = (relay_chn_tilt_ctl_t*) arg;
ESP_RETURN_VOID_ON_FALSE(tilt_ctl != NULL, TAG, "relay_chn_tilt_flush_timer_cb: timer arg is NULL");
// Save the tilt count to storage
esp_err_t ret = relay_chn_tilt_save_tilt_counter(tilt_ctl);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "relay_chn_tilt_execute_stop: Failed to save tilt count for channel #%d: %s", tilt_ctl->chn_ctl->id, esp_err_to_name(ret));
}
}
#endif
static void relay_chn_tilt_execute_stop(relay_chn_tilt_ctl_t *tilt_ctl) static void relay_chn_tilt_execute_stop(relay_chn_tilt_ctl_t *tilt_ctl)
{ {
// Stop the channel's timer if active // Stop the channel's timer if active
@@ -461,6 +513,11 @@ static void relay_chn_tilt_execute_stop(relay_chn_tilt_ctl_t *tilt_ctl)
ESP_LOGE(TAG, "relay_chn_tilt_execute_stop: Failed to output stop for relay channel #%d!", tilt_ctl->chn_ctl->id); ESP_LOGE(TAG, "relay_chn_tilt_execute_stop: Failed to output stop for relay channel #%d!", tilt_ctl->chn_ctl->id);
} }
relay_chn_dispatch_cmd(tilt_ctl->chn_ctl, RELAY_CHN_CMD_STOP); relay_chn_dispatch_cmd(tilt_ctl->chn_ctl, RELAY_CHN_CMD_STOP);
#if RELAY_CHN_ENABLE_NVS == 1
// Start the flush debounce timer
relay_chn_start_esp_timer_once(tilt_ctl->flush_timer, RELAY_CHN_TILT_FLUSH_DEBOUNCE_MS);
#endif
} }
static void relay_chn_tilt_execute_forward(relay_chn_tilt_ctl_t *tilt_ctl) static void relay_chn_tilt_execute_forward(relay_chn_tilt_ctl_t *tilt_ctl)
@@ -544,7 +601,7 @@ static void relay_chn_tilt_event_handler(void *handler_arg, esp_event_base_t eve
static void relay_chn_tilt_timer_cb(void *arg) static void relay_chn_tilt_timer_cb(void *arg)
{ {
relay_chn_tilt_ctl_t* tilt_ctl = (relay_chn_tilt_ctl_t*) arg; relay_chn_tilt_ctl_t* tilt_ctl = (relay_chn_tilt_ctl_t*) arg;
ESP_RETURN_VOID_ON_FALSE(tilt_ctl != NULL, TAG, "relay_chn_tilt_timer_cb: event_data is NULL"); ESP_RETURN_VOID_ON_FALSE(tilt_ctl != NULL, TAG, "relay_chn_tilt_timer_cb: timer arg is NULL");
switch (tilt_ctl->step) switch (tilt_ctl->step)
{ {
@@ -571,17 +628,44 @@ static void relay_chn_tilt_timer_cb(void *arg)
} }
} }
esp_err_t relay_chn_tilt_ctl_init(relay_chn_tilt_ctl_t *tilt_ctl, relay_chn_ctl_t *chn_ctl) #if RELAY_CHN_ENABLE_NVS == 1
static esp_err_t relay_chn_tilt_load_sensitivity(uint8_t ch, uint8_t *sensitivity)
{
esp_err_t ret = relay_chn_nvs_get_tilt_sensitivity(ch, sensitivity);
if (ret == ESP_ERR_NVS_NOT_FOUND) {
*sensitivity = RELAY_CHN_TILT_DEFAULT_SENSITIVITY;
return ESP_OK;
}
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to load tilt sensitivity for channel %d", ch);
return ESP_OK;
}
static esp_err_t relay_chn_tilt_load_tilt_counter(uint8_t ch, relay_chn_tilt_counter_t *tilt_counter)
{
esp_err_t ret = relay_chn_nvs_get_tilt_count(ch, &tilt_counter->tilt_forward_count, &tilt_counter->tilt_reverse_count);
if (ret == ESP_ERR_NVS_NOT_FOUND) {
ESP_LOGD(TAG, "relay_chn_tilt_load_tilt_counter: No tilt counters found in NVS for channel %d, initializing to zero", ch);
tilt_counter->tilt_forward_count = 0;
tilt_counter->tilt_reverse_count = 0;
return ESP_OK;
}
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to load tilt counters for channel %d", ch);
return ESP_OK;
}
#endif // RELAY_CHN_ENABLE_NVS
static esp_err_t relay_chn_tilt_ctl_init(relay_chn_tilt_ctl_t *tilt_ctl, relay_chn_ctl_t *chn_ctl,
relay_chn_tilt_counter_t *tilt_counter, uint8_t sensitivity)
{ {
tilt_ctl->cmd = RELAY_CHN_TILT_CMD_NONE; tilt_ctl->cmd = RELAY_CHN_TILT_CMD_NONE;
tilt_ctl->step = RELAY_CHN_TILT_STEP_NONE; tilt_ctl->step = RELAY_CHN_TILT_STEP_NONE;
tilt_ctl->tilt_timing.sensitivity = RELAY_CHN_TILT_DEFAULT_SENSITIVITY; relay_chn_tilt_compute_set_sensitivity(tilt_ctl, sensitivity);
tilt_ctl->tilt_timing.move_time_ms = RELAY_CHN_TILT_DEFAULT_RUN_MS; // Init tilt counters
tilt_ctl->tilt_timing.pause_time_ms = RELAY_CHN_TILT_DEFAULT_PAUSE_MS; tilt_ctl->tilt_counter.tilt_forward_count = tilt_counter->tilt_forward_count;
relay_chn_tilt_reset_count(tilt_ctl); tilt_ctl->tilt_counter.tilt_reverse_count = tilt_counter->tilt_reverse_count;
tilt_ctl->chn_ctl = chn_ctl; tilt_ctl->chn_ctl = chn_ctl;
tilt_ctl->chn_ctl->tilt_ctl = tilt_ctl; // tilt_ctl->chn_ctl->tilt_ctl = tilt_ctl;
// Create tilt timer for the channel // Create tilt timer for the channel
char timer_name[32]; char timer_name[32];
@@ -591,17 +675,50 @@ esp_err_t relay_chn_tilt_ctl_init(relay_chn_tilt_ctl_t *tilt_ctl, relay_chn_ctl_
.arg = tilt_ctl, .arg = tilt_ctl,
.name = timer_name .name = timer_name
}; };
return esp_timer_create(&timer_args, &tilt_ctl->tilt_timer); esp_err_t ret = esp_timer_create(&timer_args, &tilt_ctl->tilt_timer);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to create tilt timer for channel %d", chn_ctl->id);
#if RELAY_CHN_ENABLE_NVS == 1
// Create flush timer for the tilt counters
snprintf(timer_name, sizeof(timer_name), "relay_chn_%2d_tilt_flush_timer", chn_ctl->id);
timer_args.callback = relay_chn_tilt_flush_timer_cb;
timer_args.name = timer_name;
ret = esp_timer_create(&timer_args, &tilt_ctl->flush_timer);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to create tilt flush timer for channel %d", chn_ctl->id);
#endif
return ESP_OK;
} }
esp_err_t relay_chn_tilt_init(relay_chn_ctl_t *chn_ctls) esp_err_t relay_chn_tilt_init(relay_chn_ctl_t *chn_ctls)
{ {
uint8_t sensitivity;
relay_chn_tilt_counter_t tilt_counter;
#if RELAY_CHN_COUNT > 1 #if RELAY_CHN_COUNT > 1
for (int i = 0; i < RELAY_CHN_COUNT; i++) { for (int i = 0; i < RELAY_CHN_COUNT; i++) {
relay_chn_tilt_ctl_init(&tilt_ctls[i], &chn_ctls[i]); #if RELAY_CHN_ENABLE_NVS == 1
} esp_err_t ret = relay_chn_tilt_load_sensitivity(i, &sensitivity);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to load tilt sensitivity for channel %d", i);
ret = relay_chn_tilt_load_tilt_counter(i, &tilt_counter);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to load tilt counters for channel %d", i);
#else #else
relay_chn_tilt_ctl_init(&tilt_ctl, chn_ctls); sensitivity = RELAY_CHN_TILT_DEFAULT_SENSITIVITY;
tilt_counter.tilt_forward_count = 0;
tilt_counter.tilt_reverse_count = 0;
#endif // RELAY_CHN_ENABLE_NVS == 1
relay_chn_tilt_ctl_init(&tilt_ctls[i], &chn_ctls[i], &tilt_counter, sensitivity);
}
#else
sensitivity = RELAY_CHN_TILT_DEFAULT_SENSITIVITY;
tilt_counter.tilt_forward_count = 0;
tilt_counter.tilt_reverse_count = 0;
#if RELAY_CHN_ENABLE_NVS == 1
esp_err_t ret = relay_chn_tilt_load_sensitivity(0, &sensitivity);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to load tilt sensitivity for channel %d", 0);
ret = relay_chn_tilt_load_tilt_counter(0, &tilt_counter);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to load tilt counters for channel %d", 0);
#endif // RELAY_CHN_ENABLE_NVS == 1
relay_chn_tilt_ctl_init(&tilt_ctl, chn_ctls, &tilt_counter, sensitivity);
#endif // RELAY_CHN_COUNT > 1 #endif // RELAY_CHN_COUNT > 1
return esp_event_handler_register_with(relay_chn_event_loop, return esp_event_handler_register_with(relay_chn_event_loop,
@@ -616,6 +733,12 @@ void relay_chn_tilt_ctl_deinit(relay_chn_tilt_ctl_t *tilt_ctl)
esp_timer_delete(tilt_ctl->tilt_timer); esp_timer_delete(tilt_ctl->tilt_timer);
tilt_ctl->tilt_timer = NULL; tilt_ctl->tilt_timer = NULL;
} }
#if RELAY_CHN_ENABLE_NVS == 1
if (tilt_ctl->flush_timer != NULL) {
esp_timer_delete(tilt_ctl->flush_timer);
tilt_ctl->flush_timer = NULL;
}
#endif // RELAY_CHN_ENABLE_NVS == 1
} }
void relay_chn_tilt_deinit() void relay_chn_tilt_deinit()

3
test_apps/.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"C_Cpp.intelliSenseEngine": "default"
}

View File

@@ -2,6 +2,8 @@
set(srcs "test_common.c" set(srcs "test_common.c"
"test_app_main.c") "test_app_main.c")
set(incdirs ".")
# === Selective compilation based on channel count === # === Selective compilation based on channel count ===
if(CONFIG_RELAY_CHN_COUNT GREATER 1) if(CONFIG_RELAY_CHN_COUNT GREATER 1)
list(APPEND srcs "test_relay_chn_core_multi.c" list(APPEND srcs "test_relay_chn_core_multi.c"
@@ -19,11 +21,22 @@ if(CONFIG_RELAY_CHN_ENABLE_TILTING)
endif() endif()
endif() endif()
if(CONFIG_RELAY_CHN_ENABLE_NVS)
list(APPEND incdirs "../../private_include")
list(APPEND srcs "../../src/relay_chn_nvs.c")
if(CONFIG_RELAY_CHN_COUNT GREATER 1)
list(APPEND srcs "test_relay_chn_nvs_multi.c")
else()
list(APPEND srcs "test_relay_chn_nvs_single.c")
endif()
endif()
# In order for the cases defined by `TEST_CASE` to be linked into the final elf, # In order for the cases defined by `TEST_CASE` to be linked into the final elf,
# the component can be registered as WHOLE_ARCHIVE # the component can be registered as WHOLE_ARCHIVE
idf_component_register( idf_component_register(
SRCS ${srcs} SRCS ${srcs}
INCLUDE_DIRS "." INCLUDE_DIRS ${incdirs}
REQUIRES unity relay_chn REQUIRES unity relay_chn
WHOLE_ARCHIVE WHOLE_ARCHIVE
) )

View File

@@ -1,11 +1,16 @@
#include <stdbool.h>
#include "esp_log.h" #include "esp_log.h"
#include "esp_system.h" #include "esp_system.h"
#include "test_common.h"
#include "unity.h" #include "unity.h"
#include "unity_internals.h" #include "unity_internals.h"
#include "unity_test_runner.h" #include "unity_test_runner.h"
#include <stdbool.h> #include "test_common.h"
#if RELAY_CHN_ENABLE_NVS == 1
#include "nvs_flash.h"
#include "relay_chn_nvs.h"
#endif
#ifndef RELAY_CHN_UNITY_TEST_GROUP_TAG #ifndef RELAY_CHN_UNITY_TEST_GROUP_TAG
@@ -15,20 +20,60 @@
void setUp() void setUp()
{ {
g_is_component_initialized = false;
} }
void tearDown() void tearDown()
{ {
// Clean up after each test reset_channels_to_idle_state();
if (g_is_component_initialized) { }
relay_chn_destroy();
g_is_component_initialized = false; static void test_nvs_flash_init(void)
{
esp_err_t ret;
#if RELAY_CHN_NVS_CUSTOM_PARTITION == 1
ret = nvs_flash_init_partition(RELAY_CHN_NVS_CUSTOM_PARTITION_NAME);
ESP_LOGI(TEST_TAG, "test_nvs_flash_init: NVS flash init partition return: %s", esp_err_to_name(ret));
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
// NVS partition is truncated and needs to be erased
ret = nvs_flash_erase_partition(RELAY_CHN_NVS_CUSTOM_PARTITION_NAME);
if (ret == ESP_OK) {
ret = nvs_flash_init_partition(RELAY_CHN_NVS_CUSTOM_PARTITION_NAME);
} }
}
#else
ret = nvs_flash_init();
ESP_LOGI(TEST_TAG, "test_nvs_flash_init: NVS flash init return: %s", esp_err_to_name(ret));
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
// NVS partition is truncated and needs to be erased
ret = nvs_flash_erase();
if (ret == ESP_OK) {
ret = nvs_flash_init();
}
}
#endif
TEST_ESP_OK(ret);
}
static void test_nvs_flash_deinit(void)
{
esp_err_t ret;
#if RELAY_CHN_NVS_CUSTOM_PARTITION == 1
ret = nvs_flash_deinit_partition(RELAY_CHN_NVS_CUSTOM_PARTITION_NAME);
#else
ret = nvs_flash_deinit();
#endif
TEST_ESP_OK(ret);
} }
void app_main(void) void app_main(void)
{ {
// Init NVS once for all tests
test_nvs_flash_init();
// Create relay_chn once for all tests
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
UNITY_BEGIN(); UNITY_BEGIN();
// Log general test information // Log general test information
@@ -43,6 +88,13 @@ void app_main(void)
} }
UNITY_END(); UNITY_END();
// Destroy relay_chn
relay_chn_destroy();
// Deinit NVS
test_nvs_flash_deinit();
ESP_LOGI(TEST_TAG, "All tests complete."); ESP_LOGI(TEST_TAG, "All tests complete.");
esp_restart(); // Restart to invoke qemu exit esp_restart(); // Restart to invoke qemu exit

View File

@@ -4,9 +4,7 @@ const char *TEST_TAG = "RELAY_CHN_TEST";
const uint8_t relay_chn_count = CONFIG_RELAY_CHN_COUNT; const uint8_t relay_chn_count = CONFIG_RELAY_CHN_COUNT;
const uint32_t opposite_inertia_ms = CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS; const uint32_t opposite_inertia_ms = CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS;
const uint32_t test_delay_margin_ms = 50; // ms toleransı const uint32_t test_delay_margin_ms = 50; // ms tolerance
bool g_is_component_initialized = false;
// Test-wide GPIO map // Test-wide GPIO map
#if CONFIG_RELAY_CHN_COUNT > 1 #if CONFIG_RELAY_CHN_COUNT > 1
@@ -37,3 +35,18 @@ const uint8_t gpio_map[] = {4, 5};
#endif #endif
const uint8_t gpio_count = sizeof(gpio_map) / sizeof(gpio_map[0]); const uint8_t gpio_count = sizeof(gpio_map) / sizeof(gpio_map[0]);
void reset_channels_to_idle_state()
{
#if CONFIG_RELAY_CHN_COUNT > 1
relay_chn_stop(RELAY_CHN_ID_ALL);
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
for (int i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) {
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state(i));
}
#else
relay_chn_stop();
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state());
#endif
}

View File

@@ -21,3 +21,6 @@ extern const uint32_t test_delay_margin_ms;
// Init state // Init state
extern bool g_is_component_initialized; extern bool g_is_component_initialized;
// Reset channels to Idle state
void reset_channels_to_idle_state(void);

View File

@@ -22,9 +22,6 @@ TEST_CASE("relay_chn_create handles invalid arguments", "[relay_chn][core]")
// TEST_CASE: Test that relay channels initialize correctly to RELAY_CHN_STATE_IDLE // TEST_CASE: Test that relay channels initialize correctly to RELAY_CHN_STATE_IDLE
TEST_CASE("Relay channels initialize correctly to FREE state", "[relay_chn][core]") { TEST_CASE("Relay channels initialize correctly to FREE state", "[relay_chn][core]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
for (uint8_t i = 0; i < relay_chn_count; i++) { for (uint8_t i = 0; i < relay_chn_count; i++) {
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state(i)); TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state(i));
} }
@@ -32,8 +29,6 @@ TEST_CASE("Relay channels initialize correctly to FREE state", "[relay_chn][core
// TEST_CASE: Test that relays do nothing when an invlid channel id given // TEST_CASE: Test that relays do nothing when an invlid channel id given
TEST_CASE("Run forward does nothing if channel id is invalid", "[relay_chn][core]") { TEST_CASE("Run forward does nothing if channel id is invalid", "[relay_chn][core]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
for (uint8_t i = 0; i < relay_chn_count; i++) { for (uint8_t i = 0; i < relay_chn_count; i++) {
int invalid_id = relay_chn_count * 2 + i; int invalid_id = relay_chn_count * 2 + i;
relay_chn_run_forward(invalid_id); // relay_chn_run_forward returns void relay_chn_run_forward(invalid_id); // relay_chn_run_forward returns void
@@ -45,9 +40,6 @@ TEST_CASE("Run forward does nothing if channel id is invalid", "[relay_chn][core
// TEST_CASE: Test that relays run in the forward direction and update their state // TEST_CASE: Test that relays run in the forward direction and update their state
TEST_CASE("Relay channels run forward and update state", "[relay_chn][core]") { TEST_CASE("Relay channels run forward and update state", "[relay_chn][core]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
for (uint8_t i = 0; i < relay_chn_count; i++) { for (uint8_t i = 0; i < relay_chn_count; i++) {
relay_chn_run_forward(i); // relay_chn_run_forward returns void relay_chn_run_forward(i); // relay_chn_run_forward returns void
// Short delay for state to update // Short delay for state to update
@@ -58,9 +50,6 @@ TEST_CASE("Relay channels run forward and update state", "[relay_chn][core]") {
// TEST_CASE: Test that relays do nothing when an invlid channel id given // TEST_CASE: Test that relays do nothing when an invlid channel id given
TEST_CASE("Run reverse does nothing if channel id is invalid", "[relay_chn][core]") { TEST_CASE("Run reverse does nothing if channel id is invalid", "[relay_chn][core]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// Verify that no valid channels were affected // Verify that no valid channels were affected
for (uint8_t i = 0; i < relay_chn_count; i++) { for (uint8_t i = 0; i < relay_chn_count; i++) {
int invalid_id = relay_chn_count * 2 + i; int invalid_id = relay_chn_count * 2 + i;
@@ -73,9 +62,6 @@ TEST_CASE("Run reverse does nothing if channel id is invalid", "[relay_chn][core
// TEST_CASE: Test that relays run in the reverse direction and update their state // TEST_CASE: Test that relays run in the reverse direction and update their state
TEST_CASE("Relay channels run reverse and update state", "[relay_chn][core]") { TEST_CASE("Relay channels run reverse and update state", "[relay_chn][core]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
for (uint8_t i = 0; i < relay_chn_count; i++) { for (uint8_t i = 0; i < relay_chn_count; i++) {
relay_chn_run_reverse(i); // relay_chn_run_reverse returns void relay_chn_run_reverse(i); // relay_chn_run_reverse returns void
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms)); vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
@@ -88,9 +74,6 @@ TEST_CASE("Relay channels run reverse and update state", "[relay_chn][core]") {
TEST_CASE("run_forward with ID_ALL sets all channels to FORWARD", "[relay_chn][core][id_all]") TEST_CASE("run_forward with ID_ALL sets all channels to FORWARD", "[relay_chn][core][id_all]")
{ {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
relay_chn_run_forward(RELAY_CHN_ID_ALL); relay_chn_run_forward(RELAY_CHN_ID_ALL);
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms)); vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
@@ -101,9 +84,6 @@ TEST_CASE("run_forward with ID_ALL sets all channels to FORWARD", "[relay_chn][c
TEST_CASE("run_reverse with ID_ALL sets all channels to REVERSE", "[relay_chn][core][id_all]") TEST_CASE("run_reverse with ID_ALL sets all channels to REVERSE", "[relay_chn][core][id_all]")
{ {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
relay_chn_run_reverse(RELAY_CHN_ID_ALL); relay_chn_run_reverse(RELAY_CHN_ID_ALL);
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms)); vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
@@ -114,9 +94,6 @@ TEST_CASE("run_reverse with ID_ALL sets all channels to REVERSE", "[relay_chn][c
TEST_CASE("stop with ID_ALL stops all running channels", "[relay_chn][core][id_all]") TEST_CASE("stop with ID_ALL stops all running channels", "[relay_chn][core][id_all]")
{ {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// 1. Start all channels forward to ensure they are in a known running state // 1. Start all channels forward to ensure they are in a known running state
relay_chn_run_forward(RELAY_CHN_ID_ALL); relay_chn_run_forward(RELAY_CHN_ID_ALL);
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms)); vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
@@ -136,9 +113,6 @@ TEST_CASE("stop with ID_ALL stops all running channels", "[relay_chn][core][id_a
// TEST_CASE: Test that relays stop and transition to RELAY_CHN_STATE_IDLE // TEST_CASE: Test that relays stop and transition to RELAY_CHN_STATE_IDLE
// This test also verifies the transition to FREE state after a STOP command. // This test also verifies the transition to FREE state after a STOP command.
TEST_CASE("Relay channels stop and update to FREE state", "[relay_chn][core]") { TEST_CASE("Relay channels stop and update to FREE state", "[relay_chn][core]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
for (uint8_t i = 0; i < relay_chn_count; i++) { for (uint8_t i = 0; i < relay_chn_count; i++) {
// First, run forward to test stopping and transitioning to FREE state // First, run forward to test stopping and transitioning to FREE state
relay_chn_run_forward(i); // relay_chn_run_forward returns void relay_chn_run_forward(i); // relay_chn_run_forward returns void
@@ -159,9 +133,6 @@ TEST_CASE("Relay channels stop and update to FREE state", "[relay_chn][core]") {
// TEST_CASE: Get state should return UNDEFINED when id is not valid // TEST_CASE: Get state should return UNDEFINED when id is not valid
TEST_CASE("Get state returns UNDEFINED when id is invalid", "[relay_chn][core]") { TEST_CASE("Get state returns UNDEFINED when id is invalid", "[relay_chn][core]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
for (uint8_t i = 0; i < relay_chn_count; i++) { for (uint8_t i = 0; i < relay_chn_count; i++) {
int invalid_id = relay_chn_count * 2 + i; int invalid_id = relay_chn_count * 2 + i;
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_UNDEFINED, relay_chn_get_state(invalid_id)); TEST_ASSERT_EQUAL(RELAY_CHN_STATE_UNDEFINED, relay_chn_get_state(invalid_id));
@@ -177,9 +148,6 @@ TEST_CASE("Get state returns UNDEFINED when id is invalid", "[relay_chn][core]")
// TEST_CASE: Get state string should return "UNKNOWN" when id is not valid // TEST_CASE: Get state string should return "UNKNOWN" when id is not valid
TEST_CASE("Get state string returns UNKNOWN when id is invalid", "[relay_chn][core]") { TEST_CASE("Get state string returns UNKNOWN when id is invalid", "[relay_chn][core]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
for (uint8_t i = 0; i < relay_chn_count; i++) { for (uint8_t i = 0; i < relay_chn_count; i++) {
int invalid_id = relay_chn_count * 2 + i; int invalid_id = relay_chn_count * 2 + i;
TEST_ASSERT_EQUAL_STRING("UNKNOWN", relay_chn_get_state_str(invalid_id)); TEST_ASSERT_EQUAL_STRING("UNKNOWN", relay_chn_get_state_str(invalid_id));
@@ -195,9 +163,6 @@ TEST_CASE("Get state string returns UNKNOWN when id is invalid", "[relay_chn][co
// TEST_CASE: Test independent operation of multiple relay channels // TEST_CASE: Test independent operation of multiple relay channels
TEST_CASE("Multiple channels can operate independently", "[relay_chn][core]") { TEST_CASE("Multiple channels can operate independently", "[relay_chn][core]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
if (relay_chn_count >= 2) { if (relay_chn_count >= 2) {
// Start Channel 0 in forward direction // Start Channel 0 in forward direction
relay_chn_run_forward(0); // relay_chn_run_forward returns void relay_chn_run_forward(0); // relay_chn_run_forward returns void
@@ -237,9 +202,6 @@ TEST_CASE("Multiple channels can operate independently", "[relay_chn][core]") {
TEST_CASE("Forward to Reverse transition with opposite inertia", "[relay_chn][core][inertia]") { TEST_CASE("Forward to Reverse transition with opposite inertia", "[relay_chn][core][inertia]") {
uint8_t ch = 0; // Channel to test uint8_t ch = 0; // Channel to test
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// 1. Start in forward direction // 1. Start in forward direction
relay_chn_run_forward(ch); // relay_chn_run_forward returns void relay_chn_run_forward(ch); // relay_chn_run_forward returns void
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms)); // Short delay for state stabilization vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms)); // Short delay for state stabilization
@@ -261,9 +223,6 @@ TEST_CASE("Forward to Reverse transition with opposite inertia", "[relay_chn][co
TEST_CASE("Reverse to Forward transition with opposite inertia", "[relay_chn][core][inertia]") { TEST_CASE("Reverse to Forward transition with opposite inertia", "[relay_chn][core][inertia]") {
uint8_t ch = 0; uint8_t ch = 0;
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// 1. Start in reverse direction // 1. Start in reverse direction
relay_chn_run_reverse(ch); // relay_chn_run_reverse returns void relay_chn_run_reverse(ch); // relay_chn_run_reverse returns void
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms)); vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
@@ -284,9 +243,6 @@ TEST_CASE("Reverse to Forward transition with opposite inertia", "[relay_chn][co
TEST_CASE("Running in same direction does not incur inertia", "[relay_chn][core][inertia]") { TEST_CASE("Running in same direction does not incur inertia", "[relay_chn][core][inertia]") {
uint8_t ch = 0; uint8_t ch = 0;
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// 1. Start in forward direction // 1. Start in forward direction
relay_chn_run_forward(ch); // relay_chn_run_forward returns void relay_chn_run_forward(ch); // relay_chn_run_forward returns void
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms)); vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
@@ -305,9 +261,6 @@ TEST_CASE("Running in same direction does not incur inertia", "[relay_chn][core]
TEST_CASE("FREE to Running transition without inertia", "[relay_chn][core][inertia]") { TEST_CASE("FREE to Running transition without inertia", "[relay_chn][core][inertia]") {
uint8_t ch = 0; uint8_t ch = 0;
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// setUp() should have already brought the channel to FREE state // setUp() should have already brought the channel to FREE state
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state(ch)); TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state(ch));
@@ -322,8 +275,6 @@ TEST_CASE("FREE to Running transition without inertia", "[relay_chn][core][inert
TEST_CASE("Single channel direction can be flipped", "[relay_chn][core][direction]") TEST_CASE("Single channel direction can be flipped", "[relay_chn][core][direction]")
{ {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
const uint8_t ch = 0; const uint8_t ch = 0;
// 1. Initial direction should be default // 1. Initial direction should be default
@@ -346,9 +297,6 @@ TEST_CASE("Single channel direction can be flipped", "[relay_chn][core][directio
TEST_CASE("All channels direction can be flipped simultaneously", "[relay_chn][core][direction][id_all]") TEST_CASE("All channels direction can be flipped simultaneously", "[relay_chn][core][direction][id_all]")
{ {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// 1. Flip all channels // 1. Flip all channels
relay_chn_flip_direction(RELAY_CHN_ID_ALL); relay_chn_flip_direction(RELAY_CHN_ID_ALL);
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms)); vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
@@ -370,8 +318,6 @@ TEST_CASE("All channels direction can be flipped simultaneously", "[relay_chn][c
TEST_CASE("Flipping a running channel stops it and flips direction", "[relay_chn][core][direction]") TEST_CASE("Flipping a running channel stops it and flips direction", "[relay_chn][core][direction]")
{ {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
const uint8_t ch = 0; const uint8_t ch = 0;
// 1. Start channel running and verify state // 1. Start channel running and verify state
@@ -394,8 +340,6 @@ TEST_CASE("Flipping a running channel stops it and flips direction", "[relay_chn
TEST_CASE("Direction flip handles invalid channel ID gracefully", "[relay_chn][core][direction]") TEST_CASE("Direction flip handles invalid channel ID gracefully", "[relay_chn][core][direction]")
{ {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
const uint8_t invalid_ch = relay_chn_count + 5; const uint8_t invalid_ch = relay_chn_count + 5;
relay_chn_flip_direction(invalid_ch); // Call with an invalid ID relay_chn_flip_direction(invalid_ch); // Call with an invalid ID

View File

@@ -22,17 +22,11 @@ TEST_CASE("relay_chn_create handles invalid arguments", "[relay_chn][core]")
// TEST_CASE: Test that relay channels initialize correctly to RELAY_CHN_STATE_IDLE // TEST_CASE: Test that relay channels initialize correctly to RELAY_CHN_STATE_IDLE
TEST_CASE("Relay channels initialize correctly to IDLE state", "[relay_chn][core]") { TEST_CASE("Relay channels initialize correctly to IDLE state", "[relay_chn][core]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state()); TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state());
} }
// TEST_CASE: Test that relays run in the forward direction and update their state // TEST_CASE: Test that relays run in the forward direction and update their state
TEST_CASE("Relay channels run forward and update state", "[relay_chn][core]") { TEST_CASE("Relay channels run forward and update state", "[relay_chn][core]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
relay_chn_run_forward(); relay_chn_run_forward();
// Short delay for state to update // Short delay for state to update
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms)); vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
@@ -41,9 +35,6 @@ TEST_CASE("Relay channels run forward and update state", "[relay_chn][core]") {
// TEST_CASE: Test that relays run in the reverse direction and update their state // TEST_CASE: Test that relays run in the reverse direction and update their state
TEST_CASE("Relay channels run reverse and update state", "[relay_chn][core]") { TEST_CASE("Relay channels run reverse and update state", "[relay_chn][core]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
relay_chn_run_reverse(); // relay_chn_run_reverse returns void relay_chn_run_reverse(); // relay_chn_run_reverse returns void
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms)); vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_REVERSE, relay_chn_get_state()); TEST_ASSERT_EQUAL(RELAY_CHN_STATE_REVERSE, relay_chn_get_state());
@@ -53,9 +44,6 @@ TEST_CASE("Relay channels run reverse and update state", "[relay_chn][core]") {
// TEST_CASE: Test that relays stop and transition to RELAY_CHN_STATE_IDLE // TEST_CASE: Test that relays stop and transition to RELAY_CHN_STATE_IDLE
// This test also verifies the transition to IDLE state after a STOP command. // This test also verifies the transition to IDLE state after a STOP command.
TEST_CASE("Relay channels stop and update to IDLE state", "[relay_chn][core]") { TEST_CASE("Relay channels stop and update to IDLE state", "[relay_chn][core]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// First, run forward to test stopping and transitioning to IDLE state // First, run forward to test stopping and transitioning to IDLE state
relay_chn_run_forward(); relay_chn_run_forward();
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms)); vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
@@ -80,9 +68,6 @@ TEST_CASE("Relay channels stop and update to IDLE state", "[relay_chn][core]") {
// TEST_CASE: Test transition from forward to reverse with inertia and state checks // TEST_CASE: Test transition from forward to reverse with inertia and state checks
// Scenario: RELAY_CHN_STATE_FORWARD -> (relay_chn_run_reverse) -> RELAY_CHN_STATE_STOPPED -> (inertia) -> RELAY_CHN_STATE_REVERSE // Scenario: RELAY_CHN_STATE_FORWARD -> (relay_chn_run_reverse) -> RELAY_CHN_STATE_STOPPED -> (inertia) -> RELAY_CHN_STATE_REVERSE
TEST_CASE("Forward to Reverse transition with opposite inertia", "[relay_chn][core][inertia]") { TEST_CASE("Forward to Reverse transition with opposite inertia", "[relay_chn][core][inertia]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// 1. Start in forward direction // 1. Start in forward direction
relay_chn_run_forward(); relay_chn_run_forward();
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms)); // Short delay for state stabilization vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms)); // Short delay for state stabilization
@@ -102,9 +87,6 @@ TEST_CASE("Forward to Reverse transition with opposite inertia", "[relay_chn][co
// TEST_CASE: Test transition from reverse to forward with inertia and state checks // TEST_CASE: Test transition from reverse to forward with inertia and state checks
// Scenario: RELAY_CHN_STATE_REVERSE -> (relay_chn_run_forward) -> RELAY_CHN_STATE_STOPPED -> (inertia) -> RELAY_CHN_STATE_FORWARD // Scenario: RELAY_CHN_STATE_REVERSE -> (relay_chn_run_forward) -> RELAY_CHN_STATE_STOPPED -> (inertia) -> RELAY_CHN_STATE_FORWARD
TEST_CASE("Reverse to Forward transition with opposite inertia", "[relay_chn][core][inertia]") { TEST_CASE("Reverse to Forward transition with opposite inertia", "[relay_chn][core][inertia]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// 1. Start in reverse direction // 1. Start in reverse direction
relay_chn_run_reverse(); // relay_chn_run_reverse returns void relay_chn_run_reverse(); // relay_chn_run_reverse returns void
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms)); vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
@@ -123,9 +105,6 @@ TEST_CASE("Reverse to Forward transition with opposite inertia", "[relay_chn][co
// TEST_CASE: Test issuing the same run command while already running (no inertia expected) // TEST_CASE: Test issuing the same run command while already running (no inertia expected)
// Scenario: RELAY_CHN_STATE_FORWARD -> (relay_chn_run_forward) -> RELAY_CHN_STATE_FORWARD // Scenario: RELAY_CHN_STATE_FORWARD -> (relay_chn_run_forward) -> RELAY_CHN_STATE_FORWARD
TEST_CASE("Running in same direction does not incur inertia", "[relay_chn][core][inertia]") { TEST_CASE("Running in same direction does not incur inertia", "[relay_chn][core][inertia]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// 1. Start in forward direction // 1. Start in forward direction
relay_chn_run_forward(); relay_chn_run_forward();
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms)); vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
@@ -142,9 +121,6 @@ TEST_CASE("Running in same direction does not incur inertia", "[relay_chn][core]
// TEST_CASE: Test transition from IDLE state to running (no inertia expected) // TEST_CASE: Test transition from IDLE state to running (no inertia expected)
// Scenario: RELAY_CHN_STATE_IDLE -> (relay_chn_run_forward) -> RELAY_CHN_STATE_FORWARD // Scenario: RELAY_CHN_STATE_IDLE -> (relay_chn_run_forward) -> RELAY_CHN_STATE_FORWARD
TEST_CASE("IDLE to Running transition without inertia", "[relay_chn][core][inertia]") { TEST_CASE("IDLE to Running transition without inertia", "[relay_chn][core][inertia]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// setUp() should have already brought the channel to IDLE state // setUp() should have already brought the channel to IDLE state
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state()); TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state());
@@ -159,9 +135,6 @@ TEST_CASE("IDLE to Running transition without inertia", "[relay_chn][core][inert
TEST_CASE("Single channel direction can be flipped", "[relay_chn][core][direction]") TEST_CASE("Single channel direction can be flipped", "[relay_chn][core][direction]")
{ {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// 1. Initial direction should be default // 1. Initial direction should be default
TEST_ASSERT_EQUAL(RELAY_CHN_DIRECTION_DEFAULT, relay_chn_get_direction()); TEST_ASSERT_EQUAL(RELAY_CHN_DIRECTION_DEFAULT, relay_chn_get_direction());
@@ -182,9 +155,6 @@ TEST_CASE("Single channel direction can be flipped", "[relay_chn][core][directio
TEST_CASE("Flipping a running channel stops it and flips direction", "[relay_chn][core][direction]") TEST_CASE("Flipping a running channel stops it and flips direction", "[relay_chn][core][direction]")
{ {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// 1. Start channel running and verify state // 1. Start channel running and verify state
relay_chn_run_forward(); relay_chn_run_forward();
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms)); vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));

View File

@@ -37,9 +37,6 @@ static void test_listener_2(uint8_t chn_id, relay_chn_state_t old_state, relay_c
TEST_CASE("Listener is called on state change", "[relay_chn][listener]") { TEST_CASE("Listener is called on state change", "[relay_chn][listener]") {
uint8_t ch = 0; uint8_t ch = 0;
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
reset_listener_info(&listener1_info); reset_listener_info(&listener1_info);
// 1. Register the listener // 1. Register the listener
@@ -61,9 +58,6 @@ TEST_CASE("Listener is called on state change", "[relay_chn][listener]") {
TEST_CASE("Unregistered listener is not called", "[relay_chn][listener]") { TEST_CASE("Unregistered listener is not called", "[relay_chn][listener]") {
uint8_t ch = 0; uint8_t ch = 0;
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
reset_listener_info(&listener1_info); reset_listener_info(&listener1_info);
// 1. Register and then immediately unregister the listener // 1. Register and then immediately unregister the listener
@@ -80,9 +74,6 @@ TEST_CASE("Unregistered listener is not called", "[relay_chn][listener]") {
TEST_CASE("Multiple listeners are called on state change", "[relay_chn][listener]") { TEST_CASE("Multiple listeners are called on state change", "[relay_chn][listener]") {
uint8_t ch = 0; uint8_t ch = 0;
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
reset_listener_info(&listener1_info); reset_listener_info(&listener1_info);
reset_listener_info(&listener2_info); reset_listener_info(&listener2_info);
@@ -110,9 +101,6 @@ TEST_CASE("Multiple listeners are called on state change", "[relay_chn][listener
} }
TEST_CASE("Listener registration handles invalid arguments and duplicates", "[relay_chn][listener]") { TEST_CASE("Listener registration handles invalid arguments and duplicates", "[relay_chn][listener]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
reset_listener_info(&listener1_info); reset_listener_info(&listener1_info);
// 1. Registering a NULL listener should fail // 1. Registering a NULL listener should fail

View File

@@ -35,9 +35,6 @@ static void test_listener_2(uint8_t chn_id, relay_chn_state_t old_state, relay_c
// ### Listener Functionality Tests // ### Listener Functionality Tests
TEST_CASE("Listener is called on state change", "[relay_chn][listener]") { TEST_CASE("Listener is called on state change", "[relay_chn][listener]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
reset_listener_info(&listener1_info); reset_listener_info(&listener1_info);
// 1. Register the listener // 1. Register the listener
@@ -57,9 +54,6 @@ TEST_CASE("Listener is called on state change", "[relay_chn][listener]") {
} }
TEST_CASE("Unregistered listener is not called", "[relay_chn][listener]") { TEST_CASE("Unregistered listener is not called", "[relay_chn][listener]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
reset_listener_info(&listener1_info); reset_listener_info(&listener1_info);
// 1. Register and then immediately unregister the listener // 1. Register and then immediately unregister the listener
@@ -75,9 +69,6 @@ TEST_CASE("Unregistered listener is not called", "[relay_chn][listener]") {
} }
TEST_CASE("Multiple listeners are called on state change", "[relay_chn][listener]") { TEST_CASE("Multiple listeners are called on state change", "[relay_chn][listener]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
reset_listener_info(&listener1_info); reset_listener_info(&listener1_info);
reset_listener_info(&listener2_info); reset_listener_info(&listener2_info);
@@ -105,9 +96,6 @@ TEST_CASE("Multiple listeners are called on state change", "[relay_chn][listener
} }
TEST_CASE("Listener registration handles invalid arguments and duplicates", "[relay_chn][listener]") { TEST_CASE("Listener registration handles invalid arguments and duplicates", "[relay_chn][listener]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
reset_listener_info(&listener1_info); reset_listener_info(&listener1_info);
// 1. Registering a NULL listener should fail // 1. Registering a NULL listener should fail

View File

@@ -0,0 +1,140 @@
/*
* SPDX-FileCopyrightText: 2025 Kozmotronik Tech
*
* SPDX-License-Identifier: MIT
*/
#include <string.h>
#include "unity.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "relay_chn_nvs.h"
TEST_CASE("Test relay storage init/deinit", "[relay_chn][nvs]")
{
TEST_ESP_OK(relay_chn_nvs_init());
TEST_ESP_OK(relay_chn_nvs_deinit());
}
TEST_CASE("Test direction setting and getting", "[relay_chn][nvs]")
{
TEST_ESP_OK(relay_chn_nvs_init());
// Test all channels
relay_chn_direction_t dir;
relay_chn_direction_t test_directions[] = {
RELAY_CHN_DIRECTION_DEFAULT,
RELAY_CHN_DIRECTION_FLIPPED
};
for (int channel = 0; channel < 2; channel++) {
TEST_ESP_OK(relay_chn_nvs_set_direction(channel, test_directions[channel]));
TEST_ESP_OK(relay_chn_nvs_get_direction(channel, &dir));
TEST_ASSERT_EQUAL(test_directions[channel], dir);
}
TEST_ESP_OK(relay_chn_nvs_deinit());
}
TEST_CASE("Test invalid parameters", "[relay_chn][nvs]")
{
TEST_ESP_OK(relay_chn_nvs_init());
// Test NULL pointer for all channels
for (int channel = 0; channel < RELAY_CHN_COUNT; channel++) {
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, relay_chn_nvs_get_direction(channel, NULL));
}
TEST_ESP_OK(relay_chn_nvs_deinit());
}
TEST_CASE("Test relay_chn_nvs_erase_all", "[relay_chn][nvs]")
{
TEST_ESP_OK(relay_chn_nvs_init());
// Store some test data first
relay_chn_direction_t direction = RELAY_CHN_DIRECTION_FLIPPED;
for (int channel = 0; channel < RELAY_CHN_COUNT; channel++) {
TEST_ESP_OK(relay_chn_nvs_set_direction(0, direction));
}
#ifdef RELAY_CHN_ENABLE_TILTING
uint8_t sensitivity = 50;
for (int channel = 0; channel < RELAY_CHN_COUNT; channel++) {
TEST_ESP_OK(relay_chn_nvs_set_tilt_sensitivity(0, sensitivity));
TEST_ESP_OK(relay_chn_nvs_set_tilt_count(0, 100, 200));
}
#endif
// Test erase all
TEST_ESP_OK(relay_chn_nvs_erase_all());
// Verify data was erased by trying to read it back
relay_chn_direction_t read_direction;
TEST_ASSERT_EQUAL(ESP_ERR_NVS_NOT_FOUND, relay_chn_nvs_get_direction(0, &read_direction));
#ifdef RELAY_CHN_ENABLE_TILTING
uint8_t read_sensitivity;
TEST_ASSERT_EQUAL(ESP_ERR_NVS_NOT_FOUND, relay_chn_nvs_get_tilt_sensitivity(0, &read_sensitivity));
uint32_t fwd_count, rev_count;
TEST_ASSERT_EQUAL(ESP_ERR_NVS_NOT_FOUND, relay_chn_nvs_get_tilt_count(0, &fwd_count, &rev_count));
#endif
TEST_ESP_OK(relay_chn_nvs_deinit());
}
#ifdef RELAY_CHN_ENABLE_TILTING
TEST_CASE("Test sensitivity setting and getting", "[relay_chn][nvs][tilt]")
{
TEST_ESP_OK(relay_chn_nvs_init());
const uint8_t test_sensitivity = 75;
uint8_t sensitivity;
// Test all channels
for (int channel = 0; channel < RELAY_CHN_COUNT; channel++) {
TEST_ESP_OK(relay_chn_nvs_set_tilt_sensitivity(channel, test_sensitivity));
TEST_ESP_OK(relay_chn_nvs_get_tilt_sensitivity(channel, &sensitivity));
TEST_ASSERT_EQUAL(test_sensitivity, sensitivity);
}
TEST_ESP_OK(relay_chn_nvs_deinit());
}
TEST_CASE("Test tilt counter operations", "[relay_chn][nvs][tilt]")
{
TEST_ESP_OK(relay_chn_nvs_init());
const uint32_t fwd_count = 100;
const uint32_t rev_count = 200;
uint32_t fwd_read, rev_read;
// Test all channels
for (int channel = 0; channel < RELAY_CHN_COUNT; channel++) {
// Test setting counters
TEST_ESP_OK(relay_chn_nvs_set_tilt_count(channel, fwd_count, rev_count));
TEST_ESP_OK(relay_chn_nvs_get_tilt_count(channel, &fwd_read, &rev_read));
TEST_ASSERT_EQUAL(fwd_count, fwd_read);
TEST_ASSERT_EQUAL(rev_count, rev_read);
}
TEST_ESP_OK(relay_chn_nvs_deinit());
}
TEST_CASE("Test tilting invalid parameters", "[relay_chn][nvs][tilt]")
{
TEST_ESP_OK(relay_chn_nvs_init());
uint32_t fwd_count, rev_count;
// Test NULL pointers for all channels
for (int channel = 0; channel < RELAY_CHN_COUNT; channel++) {
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, relay_chn_nvs_get_tilt_sensitivity(channel, NULL));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, relay_chn_nvs_get_tilt_count(channel, NULL, &rev_count));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, relay_chn_nvs_get_tilt_count(channel, &fwd_count, NULL));
}
TEST_ESP_OK(relay_chn_nvs_deinit());
}
#endif // RELAY_CHN_ENABLE_TILTING

View File

@@ -0,0 +1,126 @@
/*
* SPDX-FileCopyrightText: 2025 Kozmotronik Tech
*
* SPDX-License-Identifier: MIT
*/
#include <string.h>
#include "unity.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "relay_chn_nvs.h"
TEST_CASE("Test relay storage init/deinit", "[relay_chn][nvs]")
{
TEST_ESP_OK(relay_chn_nvs_init());
TEST_ESP_OK(relay_chn_nvs_deinit());
}
TEST_CASE("Test direction setting and getting", "[relay_chn][nvs]")
{
TEST_ESP_OK(relay_chn_nvs_init());
// Test channel 0
TEST_ESP_OK(relay_chn_nvs_set_direction(0, RELAY_CHN_DIRECTION_DEFAULT));
relay_chn_direction_t dir;
TEST_ESP_OK(relay_chn_nvs_get_direction(0, &dir));
TEST_ASSERT_EQUAL(RELAY_CHN_DIRECTION_DEFAULT, dir);
// Test channel 1
TEST_ESP_OK(relay_chn_nvs_set_direction(0, RELAY_CHN_DIRECTION_FLIPPED));
TEST_ESP_OK(relay_chn_nvs_get_direction(0, &dir));
TEST_ASSERT_EQUAL(RELAY_CHN_DIRECTION_FLIPPED, dir);
TEST_ESP_OK(relay_chn_nvs_deinit());
}
TEST_CASE("Test invalid parameters", "[relay_chn][nvs]")
{
TEST_ESP_OK(relay_chn_nvs_init());
// Test NULL pointer
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, relay_chn_nvs_get_direction(0, NULL));
TEST_ESP_OK(relay_chn_nvs_deinit());
}
TEST_CASE("Test relay_chn_nvs_erase_all", "[relay_chn][nvs]")
{
TEST_ESP_OK(relay_chn_nvs_init());
// Store some test data first
relay_chn_direction_t direction = RELAY_CHN_DIRECTION_FLIPPED;
TEST_ESP_OK(relay_chn_nvs_set_direction(0, direction));
#ifdef RELAY_CHN_ENABLE_TILTING
uint8_t sensitivity = 50;
TEST_ESP_OK(relay_chn_nvs_set_tilt_sensitivity(0, sensitivity));
TEST_ESP_OK(relay_chn_nvs_set_tilt_count(0, 100, 200));
#endif
// Test erase all
TEST_ESP_OK(relay_chn_nvs_erase_all());
// Verify data was erased by trying to read it back
relay_chn_direction_t read_direction;
TEST_ASSERT_EQUAL(ESP_ERR_NVS_NOT_FOUND, relay_chn_nvs_get_direction(0, &read_direction));
#ifdef RELAY_CHN_ENABLE_TILTING
uint8_t read_sensitivity;
TEST_ASSERT_EQUAL(ESP_ERR_NVS_NOT_FOUND, relay_chn_nvs_get_tilt_sensitivity(0, &read_sensitivity));
uint32_t fwd_count, rev_count;
TEST_ASSERT_EQUAL(ESP_ERR_NVS_NOT_FOUND, relay_chn_nvs_get_tilt_count(0, &fwd_count, &rev_count));
#endif
TEST_ESP_OK(relay_chn_nvs_deinit());
}
#ifdef RELAY_CHN_ENABLE_TILTING
TEST_CASE("Test sensitivity setting and getting", "[relay_chn][nvs][tilt]")
{
TEST_ESP_OK(relay_chn_nvs_init());
const uint8_t test_sensitivity = 75;
TEST_ESP_OK(relay_chn_nvs_set_tilt_sensitivity(0, test_sensitivity));
uint8_t sensitivity;
TEST_ESP_OK(relay_chn_nvs_get_tilt_sensitivity(0, &sensitivity));
TEST_ASSERT_EQUAL(test_sensitivity, sensitivity);
TEST_ESP_OK(relay_chn_nvs_deinit());
}
TEST_CASE("Test tilt counter operations", "[relay_chn][nvs][tilt]")
{
TEST_ESP_OK(relay_chn_nvs_init());
const uint32_t fwd_count = 100;
const uint32_t rev_count = 200;
// Test setting counters
TEST_ESP_OK(relay_chn_nvs_set_tilt_count(0, fwd_count, rev_count));
uint32_t fwd_read, rev_read;
TEST_ESP_OK(relay_chn_nvs_get_tilt_count(0, &fwd_read, &rev_read));
TEST_ASSERT_EQUAL(fwd_count, fwd_read);
TEST_ASSERT_EQUAL(rev_count, rev_read);
TEST_ESP_OK(relay_chn_nvs_deinit());
}
TEST_CASE("Test tilting invalid parameters", "[relay_chn][nvs][tilt]")
{
TEST_ESP_OK(relay_chn_nvs_init());
uint32_t fwd_count, rev_count;
// Test NULL pointers
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, relay_chn_nvs_get_tilt_sensitivity(0, NULL));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, relay_chn_nvs_get_tilt_count(0, NULL, &rev_count));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, relay_chn_nvs_get_tilt_count(0, &fwd_count, NULL));
TEST_ESP_OK(relay_chn_nvs_deinit());
}
#endif // RELAY_CHN_ENABLE_TILTING

View File

@@ -14,6 +14,10 @@
// Helper function to prepare channel for tilt tests // Helper function to prepare channel for tilt tests
void prepare_channel_for_tilt(uint8_t chn_id, int initial_cmd) { void prepare_channel_for_tilt(uint8_t chn_id, int initial_cmd) {
// Ensure the channel reset tilt control
relay_chn_tilt_stop(chn_id);
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
// Ensure the channel has had a 'last_run_cmd' // Ensure the channel has had a 'last_run_cmd'
if (initial_cmd == RELAY_CHN_CMD_FORWARD) { if (initial_cmd == RELAY_CHN_CMD_FORWARD) {
relay_chn_run_forward(chn_id); relay_chn_run_forward(chn_id);
@@ -31,9 +35,6 @@ void prepare_channel_for_tilt(uint8_t chn_id, int initial_cmd) {
TEST_CASE("Run Forward to Tilt Forward transition with inertia", "[relay_chn][tilt][inertia]") { TEST_CASE("Run Forward to Tilt Forward transition with inertia", "[relay_chn][tilt][inertia]") {
uint8_t ch = 0; uint8_t ch = 0;
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// Prepare channel by running forward first to set last_run_cmd // Prepare channel by running forward first to set last_run_cmd
prepare_channel_for_tilt(ch, RELAY_CHN_CMD_FORWARD); prepare_channel_for_tilt(ch, RELAY_CHN_CMD_FORWARD);
@@ -58,9 +59,6 @@ TEST_CASE("Run Forward to Tilt Forward transition with inertia", "[relay_chn][ti
TEST_CASE("Run Reverse to Tilt Reverse transition with inertia", "[relay_chn][tilt][inertia]") { TEST_CASE("Run Reverse to Tilt Reverse transition with inertia", "[relay_chn][tilt][inertia]") {
uint8_t ch = 0; uint8_t ch = 0;
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// Prepare channel by running reverse first to set last_run_cmd // Prepare channel by running reverse first to set last_run_cmd
prepare_channel_for_tilt(ch, RELAY_CHN_CMD_REVERSE); prepare_channel_for_tilt(ch, RELAY_CHN_CMD_REVERSE);
@@ -83,9 +81,6 @@ TEST_CASE("Run Reverse to Tilt Reverse transition with inertia", "[relay_chn][ti
TEST_CASE("FREE to Tilt Forward transition with inertia (prepared)", "[relay_chn][tilt][inertia]") { TEST_CASE("FREE to Tilt Forward transition with inertia (prepared)", "[relay_chn][tilt][inertia]") {
uint8_t ch = 0; uint8_t ch = 0;
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// Prepare channel by running forward first to set last_run_cmd // Prepare channel by running forward first to set last_run_cmd
prepare_channel_for_tilt(ch, RELAY_CHN_CMD_FORWARD); prepare_channel_for_tilt(ch, RELAY_CHN_CMD_FORWARD);
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state(ch)); // Ensure we are back to FREE TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state(ch)); // Ensure we are back to FREE
@@ -102,9 +97,6 @@ TEST_CASE("FREE to Tilt Forward transition with inertia (prepared)", "[relay_chn
TEST_CASE("FREE to Tilt Reverse transition with inertia (prepared)", "[relay_chn][tilt][inertia]") { TEST_CASE("FREE to Tilt Reverse transition with inertia (prepared)", "[relay_chn][tilt][inertia]") {
uint8_t ch = 0; uint8_t ch = 0;
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// Prepare channel by running reverse first to set last_run_cmd // Prepare channel by running reverse first to set last_run_cmd
prepare_channel_for_tilt(ch, RELAY_CHN_CMD_REVERSE); prepare_channel_for_tilt(ch, RELAY_CHN_CMD_REVERSE);
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state(ch)); // Ensure we are back to FREE TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state(ch)); // Ensure we are back to FREE
@@ -120,9 +112,6 @@ TEST_CASE("FREE to Tilt Reverse transition with inertia (prepared)", "[relay_chn
TEST_CASE("Tilt Forward to Run Forward transition with inertia", "[relay_chn][tilt][inertia]") { TEST_CASE("Tilt Forward to Run Forward transition with inertia", "[relay_chn][tilt][inertia]") {
uint8_t ch = 0; uint8_t ch = 0;
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// Prepare channel by running forward first to set last_run_cmd, then tilt // Prepare channel by running forward first to set last_run_cmd, then tilt
prepare_channel_for_tilt(ch, RELAY_CHN_CMD_FORWARD); prepare_channel_for_tilt(ch, RELAY_CHN_CMD_FORWARD);
relay_chn_tilt_forward(ch); // Go to tilt state relay_chn_tilt_forward(ch); // Go to tilt state
@@ -142,9 +131,6 @@ TEST_CASE("Tilt Forward to Run Forward transition with inertia", "[relay_chn][ti
TEST_CASE("Tilt Reverse to Run Reverse transition with inertia", "[relay_chn][tilt][inertia]") { TEST_CASE("Tilt Reverse to Run Reverse transition with inertia", "[relay_chn][tilt][inertia]") {
uint8_t ch = 0; uint8_t ch = 0;
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// Prepare channel by running reverse first to set last_run_cmd, then tilt // Prepare channel by running reverse first to set last_run_cmd, then tilt
prepare_channel_for_tilt(ch, RELAY_CHN_CMD_REVERSE); prepare_channel_for_tilt(ch, RELAY_CHN_CMD_REVERSE);
relay_chn_tilt_reverse(ch); // Go to tilt state relay_chn_tilt_reverse(ch); // Go to tilt state
@@ -163,9 +149,6 @@ TEST_CASE("Tilt Reverse to Run Reverse transition with inertia", "[relay_chn][ti
TEST_CASE("Tilt Forward to Run Reverse transition without inertia", "[relay_chn][tilt][inertia]") { TEST_CASE("Tilt Forward to Run Reverse transition without inertia", "[relay_chn][tilt][inertia]") {
uint8_t ch = 0; uint8_t ch = 0;
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// Prepare channel by running forward first to set last_run_cmd, then tilt // Prepare channel by running forward first to set last_run_cmd, then tilt
prepare_channel_for_tilt(ch, RELAY_CHN_CMD_FORWARD); prepare_channel_for_tilt(ch, RELAY_CHN_CMD_FORWARD);
relay_chn_tilt_forward(ch); // Go to tilt state relay_chn_tilt_forward(ch); // Go to tilt state
@@ -183,9 +166,6 @@ TEST_CASE("Tilt Forward to Run Reverse transition without inertia", "[relay_chn]
TEST_CASE("Tilt to Stop transition without immediate inertia for stop", "[relay_chn][tilt][inertia]") { TEST_CASE("Tilt to Stop transition without immediate inertia for stop", "[relay_chn][tilt][inertia]") {
uint8_t ch = 0; uint8_t ch = 0;
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// Prepare channel by running forward first to set last_run_cmd, then tilt // Prepare channel by running forward first to set last_run_cmd, then tilt
prepare_channel_for_tilt(ch, RELAY_CHN_CMD_FORWARD); prepare_channel_for_tilt(ch, RELAY_CHN_CMD_FORWARD);
relay_chn_tilt_forward(ch); // Go to tilt state relay_chn_tilt_forward(ch); // Go to tilt state
@@ -203,9 +183,6 @@ TEST_CASE("Tilt to Stop transition without immediate inertia for stop", "[relay_
TEST_CASE("tilt_forward with ID_ALL sets all channels to TILT_FORWARD", "[relay_chn][tilt][id_all]") TEST_CASE("tilt_forward with ID_ALL sets all channels to TILT_FORWARD", "[relay_chn][tilt][id_all]")
{ {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// 1. Prepare all channels. // 1. Prepare all channels.
for (uint8_t i = 0; i < relay_chn_count; i++) { for (uint8_t i = 0; i < relay_chn_count; i++) {
prepare_channel_for_tilt(i, RELAY_CHN_CMD_FORWARD); prepare_channel_for_tilt(i, RELAY_CHN_CMD_FORWARD);
@@ -223,9 +200,6 @@ TEST_CASE("tilt_forward with ID_ALL sets all channels to TILT_FORWARD", "[relay_
TEST_CASE("tilt_reverse with ID_ALL sets all channels to TILT_REVERSE", "[relay_chn][tilt][id_all]") TEST_CASE("tilt_reverse with ID_ALL sets all channels to TILT_REVERSE", "[relay_chn][tilt][id_all]")
{ {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// 1. Prepare all channels. // 1. Prepare all channels.
for (uint8_t i = 0; i < relay_chn_count; i++) { for (uint8_t i = 0; i < relay_chn_count; i++) {
prepare_channel_for_tilt(i, RELAY_CHN_CMD_REVERSE); prepare_channel_for_tilt(i, RELAY_CHN_CMD_REVERSE);
@@ -243,9 +217,6 @@ TEST_CASE("tilt_reverse with ID_ALL sets all channels to TILT_REVERSE", "[relay_
TEST_CASE("tilt_stop with ID_ALL stops all tilting channels", "[relay_chn][tilt][id_all]") TEST_CASE("tilt_stop with ID_ALL stops all tilting channels", "[relay_chn][tilt][id_all]")
{ {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// 1. Prepare and start all channels tilting forward // 1. Prepare and start all channels tilting forward
for (uint8_t i = 0; i < relay_chn_count; i++) { for (uint8_t i = 0; i < relay_chn_count; i++) {
prepare_channel_for_tilt(i, RELAY_CHN_CMD_REVERSE); prepare_channel_for_tilt(i, RELAY_CHN_CMD_REVERSE);
@@ -265,9 +236,6 @@ TEST_CASE("tilt_stop with ID_ALL stops all tilting channels", "[relay_chn][tilt]
TEST_CASE("tilt_auto with ID_ALL tilts channels based on last run direction", "[relay_chn][tilt][id_all]") TEST_CASE("tilt_auto with ID_ALL tilts channels based on last run direction", "[relay_chn][tilt][id_all]")
{ {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// This test requires at least 2 channels to demonstrate different behaviors // This test requires at least 2 channels to demonstrate different behaviors
TEST_ASSERT_GREATER_OR_EQUAL_MESSAGE(2, relay_chn_count, "Test requires at least 2 channels"); TEST_ASSERT_GREATER_OR_EQUAL_MESSAGE(2, relay_chn_count, "Test requires at least 2 channels");
@@ -287,9 +255,6 @@ TEST_CASE("tilt_auto with ID_ALL tilts channels based on last run direction", "[
// Test relay_chn_tilt_auto() chooses correct tilt direction // Test relay_chn_tilt_auto() chooses correct tilt direction
TEST_CASE("relay_chn_tilt_auto chooses correct direction", "[relay_chn][tilt][auto]") { TEST_CASE("relay_chn_tilt_auto chooses correct direction", "[relay_chn][tilt][auto]") {
uint8_t ch = 0; uint8_t ch = 0;
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// Prepare FORWARD // Prepare FORWARD
prepare_channel_for_tilt(ch, RELAY_CHN_CMD_FORWARD); prepare_channel_for_tilt(ch, RELAY_CHN_CMD_FORWARD);
relay_chn_tilt_auto(ch); relay_chn_tilt_auto(ch);
@@ -309,9 +274,6 @@ TEST_CASE("relay_chn_tilt_auto chooses correct direction", "[relay_chn][tilt][au
TEST_CASE("relay_chn_tilt_set_sensitivity and get", "[relay_chn][tilt][sensitivity]") { TEST_CASE("relay_chn_tilt_set_sensitivity and get", "[relay_chn][tilt][sensitivity]") {
uint8_t ch = 0; uint8_t ch = 0;
uint8_t val = 0; uint8_t val = 0;
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
relay_chn_tilt_set_sensitivity(ch, 0); relay_chn_tilt_set_sensitivity(ch, 0);
TEST_ESP_OK(relay_chn_tilt_get_sensitivity(ch, &val, 1)); TEST_ESP_OK(relay_chn_tilt_get_sensitivity(ch, &val, 1));
TEST_ASSERT_EQUAL_UINT8(0, val); TEST_ASSERT_EQUAL_UINT8(0, val);
@@ -336,9 +298,6 @@ TEST_CASE("relay_chn_tilt_set_sensitivity and get", "[relay_chn][tilt][sensitivi
// Test tilt counter logic: forward x3, reverse x3, extra reverse fails // Test tilt counter logic: forward x3, reverse x3, extra reverse fails
TEST_CASE("tilt counter logic: forward and reverse consumption", "[relay_chn][tilt][counter]") { TEST_CASE("tilt counter logic: forward and reverse consumption", "[relay_chn][tilt][counter]") {
uint8_t ch = 0; uint8_t ch = 0;
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
prepare_channel_for_tilt(ch, RELAY_CHN_CMD_FORWARD); prepare_channel_for_tilt(ch, RELAY_CHN_CMD_FORWARD);
// Tilt forward 3 times // Tilt forward 3 times
@@ -372,9 +331,6 @@ TEST_CASE("tilt counter logic: forward and reverse consumption", "[relay_chn][ti
// Test run command during TILT state // Test run command during TILT state
TEST_CASE("run command during TILT state transitions correctly", "[relay_chn][tilt][run-during-tilt]") { TEST_CASE("run command during TILT state transitions correctly", "[relay_chn][tilt][run-during-tilt]") {
uint8_t ch = 0; uint8_t ch = 0;
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
prepare_channel_for_tilt(ch, RELAY_CHN_CMD_FORWARD); prepare_channel_for_tilt(ch, RELAY_CHN_CMD_FORWARD);
relay_chn_tilt_forward(ch); relay_chn_tilt_forward(ch);
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms)); vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));

View File

@@ -14,6 +14,10 @@
// Helper function to prepare channel for tilt tests // Helper function to prepare channel for tilt tests
void prepare_channel_for_tilt(int initial_cmd) { void prepare_channel_for_tilt(int initial_cmd) {
// Ensure the channel reset tilt control
relay_chn_tilt_stop();
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
// Ensure the channel has had a 'last_run_cmd' // Ensure the channel has had a 'last_run_cmd'
if (initial_cmd == RELAY_CHN_CMD_FORWARD) { if (initial_cmd == RELAY_CHN_CMD_FORWARD) {
relay_chn_run_forward(); relay_chn_run_forward();
@@ -29,9 +33,6 @@ void prepare_channel_for_tilt(int initial_cmd) {
// TEST_CASE: Test transition from running forward to tilt forward // TEST_CASE: Test transition from running forward to tilt forward
// Scenario: RELAY_CHN_STATE_FORWARD -> (relay_chn_tilt_forward) -> RELAY_CHN_STATE_STOPPED -> (inertia) -> RELAY_CHN_STATE_TILT_FORWARD // Scenario: RELAY_CHN_STATE_FORWARD -> (relay_chn_tilt_forward) -> RELAY_CHN_STATE_STOPPED -> (inertia) -> RELAY_CHN_STATE_TILT_FORWARD
TEST_CASE("Run Forward to Tilt Forward transition with inertia", "[relay_chn][tilt][inertia]") { TEST_CASE("Run Forward to Tilt Forward transition with inertia", "[relay_chn][tilt][inertia]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// Prepare channel by running forward first to set last_run_cmd // Prepare channel by running forward first to set last_run_cmd
prepare_channel_for_tilt(RELAY_CHN_CMD_FORWARD); prepare_channel_for_tilt(RELAY_CHN_CMD_FORWARD);
@@ -54,9 +55,6 @@ TEST_CASE("Run Forward to Tilt Forward transition with inertia", "[relay_chn][ti
// TEST_CASE: Test transition from running reverse to tilt reverse // TEST_CASE: Test transition from running reverse to tilt reverse
// Scenario: RELAY_CHN_STATE_REVERSE -> (relay_chn_tilt_reverse) -> RELAY_CHN_STATE_STOPPED -> (inertia) -> RELAY_CHN_STATE_TILT_REVERSE // Scenario: RELAY_CHN_STATE_REVERSE -> (relay_chn_tilt_reverse) -> RELAY_CHN_STATE_STOPPED -> (inertia) -> RELAY_CHN_STATE_TILT_REVERSE
TEST_CASE("Run Reverse to Tilt Reverse transition with inertia", "[relay_chn][tilt][inertia]") { TEST_CASE("Run Reverse to Tilt Reverse transition with inertia", "[relay_chn][tilt][inertia]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// Prepare channel by running reverse first to set last_run_cmd // Prepare channel by running reverse first to set last_run_cmd
prepare_channel_for_tilt(RELAY_CHN_CMD_REVERSE); prepare_channel_for_tilt(RELAY_CHN_CMD_REVERSE);
@@ -77,9 +75,6 @@ TEST_CASE("Run Reverse to Tilt Reverse transition with inertia", "[relay_chn][ti
// TEST_CASE: Test transition from FREE state to tilt forward (now with preparation) // TEST_CASE: Test transition from FREE state to tilt forward (now with preparation)
// Scenario: RELAY_CHN_STATE_IDLE -> (prepare) -> RELAY_CHN_STATE_IDLE -> (relay_chn_tilt_forward) -> RELAY_CHN_STATE_STOPPED -> (inertia) -> RELAY_CHN_STATE_TILT_FORWARD // Scenario: RELAY_CHN_STATE_IDLE -> (prepare) -> RELAY_CHN_STATE_IDLE -> (relay_chn_tilt_forward) -> RELAY_CHN_STATE_STOPPED -> (inertia) -> RELAY_CHN_STATE_TILT_FORWARD
TEST_CASE("FREE to Tilt Forward transition with inertia (prepared)", "[relay_chn][tilt][inertia]") { TEST_CASE("FREE to Tilt Forward transition with inertia (prepared)", "[relay_chn][tilt][inertia]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// Prepare channel by running forward first to set last_run_cmd // Prepare channel by running forward first to set last_run_cmd
prepare_channel_for_tilt(RELAY_CHN_CMD_FORWARD); prepare_channel_for_tilt(RELAY_CHN_CMD_FORWARD);
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state()); // Ensure we are back to FREE TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state()); // Ensure we are back to FREE
@@ -94,9 +89,6 @@ TEST_CASE("FREE to Tilt Forward transition with inertia (prepared)", "[relay_chn
// TEST_CASE: Test transition from FREE state to tilt reverse (now with preparation) // TEST_CASE: Test transition from FREE state to tilt reverse (now with preparation)
// Scenario: RELAY_CHN_STATE_IDLE -> (prepare) -> RELAY_CHN_STATE_IDLE -> (relay_chn_tilt_reverse) -> RELAY_CHN_STATE_STOPPED -> (inertia) -> RELAY_CHN_STATE_TILT_REVERSE // Scenario: RELAY_CHN_STATE_IDLE -> (prepare) -> RELAY_CHN_STATE_IDLE -> (relay_chn_tilt_reverse) -> RELAY_CHN_STATE_STOPPED -> (inertia) -> RELAY_CHN_STATE_TILT_REVERSE
TEST_CASE("FREE to Tilt Reverse transition with inertia (prepared)", "[relay_chn][tilt][inertia]") { TEST_CASE("FREE to Tilt Reverse transition with inertia (prepared)", "[relay_chn][tilt][inertia]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// Prepare channel by running reverse first to set last_run_cmd // Prepare channel by running reverse first to set last_run_cmd
prepare_channel_for_tilt(RELAY_CHN_CMD_REVERSE); prepare_channel_for_tilt(RELAY_CHN_CMD_REVERSE);
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state()); // Ensure we are back to FREE TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state()); // Ensure we are back to FREE
@@ -110,9 +102,6 @@ TEST_CASE("FREE to Tilt Reverse transition with inertia (prepared)", "[relay_chn
// TEST_CASE: Test transition from tilt forward to run forward (inertia expected for run) // TEST_CASE: Test transition from tilt forward to run forward (inertia expected for run)
// Scenario: RELAY_CHN_STATE_TILT_FORWARD -> (relay_chn_run_forward) -> RELAY_CHN_STATE_FORWARD // Scenario: RELAY_CHN_STATE_TILT_FORWARD -> (relay_chn_run_forward) -> RELAY_CHN_STATE_FORWARD
TEST_CASE("Tilt Forward to Run Forward transition with inertia", "[relay_chn][tilt][inertia]") { TEST_CASE("Tilt Forward to Run Forward transition with inertia", "[relay_chn][tilt][inertia]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// Prepare channel by running forward first to set last_run_cmd, then tilt // Prepare channel by running forward first to set last_run_cmd, then tilt
prepare_channel_for_tilt(RELAY_CHN_CMD_FORWARD); prepare_channel_for_tilt(RELAY_CHN_CMD_FORWARD);
relay_chn_tilt_forward(); // Go to tilt state relay_chn_tilt_forward(); // Go to tilt state
@@ -130,9 +119,6 @@ TEST_CASE("Tilt Forward to Run Forward transition with inertia", "[relay_chn][ti
// TEST_CASE: Test transition from tilt reverse to run reverse (no inertia expected for run) // TEST_CASE: Test transition from tilt reverse to run reverse (no inertia expected for run)
// Scenario: RELAY_CHN_STATE_TILT_REVERSE -> (relay_chn_run_reverse) -> RELAY_CHN_STATE_REVERSE // Scenario: RELAY_CHN_STATE_TILT_REVERSE -> (relay_chn_run_reverse) -> RELAY_CHN_STATE_REVERSE
TEST_CASE("Tilt Reverse to Run Reverse transition with inertia", "[relay_chn][tilt][inertia]") { TEST_CASE("Tilt Reverse to Run Reverse transition with inertia", "[relay_chn][tilt][inertia]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// Prepare channel by running reverse first to set last_run_cmd, then tilt // Prepare channel by running reverse first to set last_run_cmd, then tilt
prepare_channel_for_tilt(RELAY_CHN_CMD_REVERSE); prepare_channel_for_tilt(RELAY_CHN_CMD_REVERSE);
relay_chn_tilt_reverse(); // Go to tilt state relay_chn_tilt_reverse(); // Go to tilt state
@@ -149,9 +135,6 @@ TEST_CASE("Tilt Reverse to Run Reverse transition with inertia", "[relay_chn][ti
// TEST_CASE: Test transition from tilt forward to run reverse (without inertia) // TEST_CASE: Test transition from tilt forward to run reverse (without inertia)
// Scenario: RELAY_CHN_STATE_TILT_FORWARD -> (relay_chn_run_reverse) -> RELAY_CHN_STATE_REVERSE // Scenario: RELAY_CHN_STATE_TILT_FORWARD -> (relay_chn_run_reverse) -> RELAY_CHN_STATE_REVERSE
TEST_CASE("Tilt Forward to Run Reverse transition without inertia", "[relay_chn][tilt][inertia]") { TEST_CASE("Tilt Forward to Run Reverse transition without inertia", "[relay_chn][tilt][inertia]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// Prepare channel by running forward first to set last_run_cmd, then tilt // Prepare channel by running forward first to set last_run_cmd, then tilt
prepare_channel_for_tilt(RELAY_CHN_CMD_FORWARD); prepare_channel_for_tilt(RELAY_CHN_CMD_FORWARD);
relay_chn_tilt_forward(); // Go to tilt state relay_chn_tilt_forward(); // Go to tilt state
@@ -167,9 +150,6 @@ TEST_CASE("Tilt Forward to Run Reverse transition without inertia", "[relay_chn]
// TEST_CASE: Test stopping from a tilt state (no inertia for stop command itself) // TEST_CASE: Test stopping from a tilt state (no inertia for stop command itself)
// Scenario: RELAY_CHN_STATE_TILT_FORWARD -> (relay_chn_stop) -> RELAY_CHN_STATE_STOPPED -> (inertia) -> RELAY_CHN_STATE_IDLE // Scenario: RELAY_CHN_STATE_TILT_FORWARD -> (relay_chn_stop) -> RELAY_CHN_STATE_STOPPED -> (inertia) -> RELAY_CHN_STATE_IDLE
TEST_CASE("Tilt to Stop transition without immediate inertia for stop", "[relay_chn][tilt][inertia]") { TEST_CASE("Tilt to Stop transition without immediate inertia for stop", "[relay_chn][tilt][inertia]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// Prepare channel by running forward first to set last_run_cmd, then tilt // Prepare channel by running forward first to set last_run_cmd, then tilt
prepare_channel_for_tilt(RELAY_CHN_CMD_FORWARD); prepare_channel_for_tilt(RELAY_CHN_CMD_FORWARD);
relay_chn_tilt_forward(); // Go to tilt state relay_chn_tilt_forward(); // Go to tilt state
@@ -185,9 +165,6 @@ TEST_CASE("Tilt to Stop transition without immediate inertia for stop", "[relay_
// Test relay_chn_tilt_auto() chooses correct tilt direction // Test relay_chn_tilt_auto() chooses correct tilt direction
TEST_CASE("relay_chn_tilt_auto chooses correct direction", "[relay_chn][tilt][auto]") { TEST_CASE("relay_chn_tilt_auto chooses correct direction", "[relay_chn][tilt][auto]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
// Prepare FORWARD // Prepare FORWARD
prepare_channel_for_tilt(RELAY_CHN_CMD_FORWARD); prepare_channel_for_tilt(RELAY_CHN_CMD_FORWARD);
relay_chn_tilt_auto(); relay_chn_tilt_auto();
@@ -205,9 +182,6 @@ TEST_CASE("relay_chn_tilt_auto chooses correct direction", "[relay_chn][tilt][au
// Test sensitivity set/get // Test sensitivity set/get
TEST_CASE("relay_chn_tilt_set_sensitivity and get", "[relay_chn][tilt][sensitivity]") { TEST_CASE("relay_chn_tilt_set_sensitivity and get", "[relay_chn][tilt][sensitivity]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
relay_chn_tilt_set_sensitivity(0); relay_chn_tilt_set_sensitivity(0);
TEST_ASSERT_EQUAL_UINT8(0, relay_chn_tilt_get_sensitivity()); TEST_ASSERT_EQUAL_UINT8(0, relay_chn_tilt_get_sensitivity());
@@ -223,9 +197,6 @@ TEST_CASE("relay_chn_tilt_set_sensitivity and get", "[relay_chn][tilt][sensitivi
// Test tilt counter logic: forward x3, reverse x3, extra reverse fails // Test tilt counter logic: forward x3, reverse x3, extra reverse fails
TEST_CASE("tilt counter logic: forward and reverse consumption", "[relay_chn][tilt][counter]") { TEST_CASE("tilt counter logic: forward and reverse consumption", "[relay_chn][tilt][counter]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
prepare_channel_for_tilt(RELAY_CHN_CMD_FORWARD); prepare_channel_for_tilt(RELAY_CHN_CMD_FORWARD);
// Tilt forward 3 times // Tilt forward 3 times
@@ -258,9 +229,6 @@ TEST_CASE("tilt counter logic: forward and reverse consumption", "[relay_chn][ti
// Test run command during TILT state // Test run command during TILT state
TEST_CASE("run command during TILT state transitions correctly", "[relay_chn][tilt][run-during-tilt]") { TEST_CASE("run command during TILT state transitions correctly", "[relay_chn][tilt][run-during-tilt]") {
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
g_is_component_initialized = true;
prepare_channel_for_tilt(RELAY_CHN_CMD_FORWARD); prepare_channel_for_tilt(RELAY_CHN_CMD_FORWARD);
relay_chn_tilt_forward(); relay_chn_tilt_forward();
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms)); vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));

View File

@@ -1,5 +0,0 @@
# ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size, Flags
nvs,data,nvs,0xa000,24K,
phy_init,data,phy,0x10000,4K,
factory,app,factory,0x20000,1M,
1 # ESP-IDF Partition Table
2 # Name, Type, SubType, Offset, Size, Flags
3 nvs,data,nvs,0xa000,24K,
4 phy_init,data,phy,0x10000,4K,
5 factory,app,factory,0x20000,1M,

View File

@@ -0,0 +1,6 @@
# ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size, Flags
nvs,data,nvs,0xa000,24K,,
phy_init,data,phy,0x10000,4K,,
factory,app,factory,0x20000,1M,,
app_data,data,nvs,,8K,,
1 # ESP-IDF Partition Table
2 # Name, Type, SubType, Offset, Size, Flags
3 nvs,data,nvs,0xa000,24K,,
4 phy_init,data,phy,0x10000,4K,,
5 factory,app,factory,0x20000,1M,,
6 app_data,data,nvs,,8K,,

View File

@@ -395,13 +395,13 @@ CONFIG_ESPTOOLPY_MONITOR_BAUD=115200
# #
# Partition Table # Partition Table
# #
CONFIG_PARTITION_TABLE_SINGLE_APP=y # CONFIG_PARTITION_TABLE_SINGLE_APP is not set
# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set # CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set
# CONFIG_PARTITION_TABLE_TWO_OTA is not set # CONFIG_PARTITION_TABLE_TWO_OTA is not set
# CONFIG_PARTITION_TABLE_TWO_OTA_LARGE is not set # CONFIG_PARTITION_TABLE_TWO_OTA_LARGE is not set
# CONFIG_PARTITION_TABLE_CUSTOM is not set CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions/part_nvs.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" CONFIG_PARTITION_TABLE_FILENAME="partitions/part_nvs.csv"
CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_OFFSET=0x8000
CONFIG_PARTITION_TABLE_MD5=y CONFIG_PARTITION_TABLE_MD5=y
# end of Partition Table # end of Partition Table
@@ -1162,6 +1162,13 @@ CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y
# CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set # CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set
# end of Newlib # end of Newlib
#
# NVS
#
# CONFIG_NVS_ASSERT_ERROR_CHECK is not set
# CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set
# end of NVS
# #
# PThreads # PThreads
# #
@@ -1263,7 +1270,16 @@ CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS=200 CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS=200
CONFIG_RELAY_CHN_COUNT=1 CONFIG_RELAY_CHN_COUNT=1
CONFIG_RELAY_CHN_ENABLE_TILTING=y CONFIG_RELAY_CHN_ENABLE_TILTING=y
CONFIG_RELAY_CHN_ENABLE_NVS=y
# end of Relay Channel Driver Configuration # end of Relay Channel Driver Configuration
#
# Relay Channel NVS Storage Configuration
#
CONFIG_RELAY_CHN_NVS_NAMESPACE="relay_chn"
CONFIG_RELAY_CHN_NVS_CUSTOM_PARTITION=y
CONFIG_RELAY_CHN_NVS_CUSTOM_PARTITION_NAME="app_data"
# end of Relay Channel NVS Storage Configuration
# end of Component config # end of Component config
# CONFIG_IDF_EXPERIMENTAL_FEATURES is not set # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set

View File

@@ -6,3 +6,4 @@ CONFIG_ESP_TASK_WDT_INIT=n
CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS=200 CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS=200
CONFIG_RELAY_CHN_COUNT=2 CONFIG_RELAY_CHN_COUNT=2
CONFIG_RELAY_CHN_ENABLE_TILTING=y CONFIG_RELAY_CHN_ENABLE_TILTING=y
CONFIG_RELAY_CHN_ENABLE_NVS=y

View File

@@ -0,0 +1,15 @@
# Disable task WDT for tests
CONFIG_ESP_TASK_WDT_INIT=n
# Partition configuration
CONFIG_PARTITION_TABLE_SINGLE_APP=y
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions/part_nvs.csv"
# Relay Channel Driver Default Configuration for Testing
# Keep this as short as possible for tests
CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS=200
CONFIG_RELAY_CHN_COUNT=2
CONFIG_RELAY_CHN_ENABLE_TILTING=y
CONFIG_RELAY_CHN_ENABLE_NVS=y
CONFIG_RELAY_CHN_NVS_CUSTOM_PARTITION=y

View File

@@ -6,3 +6,4 @@ CONFIG_ESP_TASK_WDT_INIT=n
CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS=200 CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS=200
CONFIG_RELAY_CHN_COUNT=1 CONFIG_RELAY_CHN_COUNT=1
CONFIG_RELAY_CHN_ENABLE_TILTING=y CONFIG_RELAY_CHN_ENABLE_TILTING=y
CONFIG_RELAY_CHN_ENABLE_NVS=y

View File

@@ -0,0 +1,15 @@
# Disable task WDT for tests
CONFIG_ESP_TASK_WDT_INIT=n
# Partition configuration
CONFIG_PARTITION_TABLE_SINGLE_APP=y
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions/part_nvs.csv"
# Relay Channel Driver Default Configuration for Testing
# Keep this as short as possible for tests
CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS=200
CONFIG_RELAY_CHN_COUNT=1
CONFIG_RELAY_CHN_ENABLE_TILTING=y
CONFIG_RELAY_CHN_ENABLE_NVS=y
CONFIG_RELAY_CHN_NVS_CUSTOM_PARTITION=y