Compare commits
1 Commits
bb1d5fe842
...
feat/1029-
| Author | SHA1 | Date | |
|---|---|---|---|
|
6860dba4d7
|
21
.vscode/settings.json
vendored
21
.vscode/settings.json
vendored
@@ -1,23 +1,6 @@
|
|||||||
{
|
{
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"relay_chn.h": "c",
|
"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.port": "/dev/ttyUSB0"
|
||||||
"idf.pythonInstallPath": "/usr/bin/python"
|
|
||||||
}
|
}
|
||||||
@@ -1,21 +1,4 @@
|
|||||||
set(include_dirs "include")
|
idf_component_register(SRCS "src/relay_chn.c"
|
||||||
set(priv_include_dirs "private_include")
|
INCLUDE_DIRS include
|
||||||
|
REQUIRES driver
|
||||||
set(srcs "src/relay_chn_core.c"
|
PRIV_REQUIRES esp_timer esp_event)
|
||||||
"src/relay_chn_output.c"
|
|
||||||
"src/relay_chn_run_info.c")
|
|
||||||
|
|
||||||
if(CONFIG_RELAY_CHN_ENABLE_TILTING)
|
|
||||||
list(APPEND srcs "src/relay_chn_tilt.c")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CONFIG_RELAY_CHN_COUNT GREATER 1)
|
|
||||||
list(APPEND srcs "src/relay_chn_ctl_multi.c")
|
|
||||||
else()
|
|
||||||
list(APPEND srcs "src/relay_chn_ctl_single.c")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
idf_component_register(SRCS ${srcs}
|
|
||||||
INCLUDE_DIRS ${include_dirs}
|
|
||||||
PRIV_INCLUDE_DIRS ${priv_include_dirs}
|
|
||||||
REQUIRES driver esp_timer esp_event)
|
|
||||||
|
|||||||
136
README.md
136
README.md
@@ -43,28 +43,11 @@ dependencies:
|
|||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
The `relay_chn` component can be used in two different modes, which are determined by the 'CONFIG_RELAY_CHN_COUNT' configuration:
|
|
||||||
|
|
||||||
- Single channel mode (`CONFIG_RELAY_CHN_COUNT == 1`)
|
|
||||||
- Multi channel mode (`CONFIG_RELAY_CHN_COUNT > 1`)
|
|
||||||
|
|
||||||
Depending on the mode, the component will be built selectively, so the signatures of some available API functions may vary, either including or excluding a channel ID parameter:
|
|
||||||
|
|
||||||
```c
|
|
||||||
relay_chn_run_forward(); // No channel ID parameter for single channel mode
|
|
||||||
// or
|
|
||||||
relay_chn_run_forward(2); // Channel ID parameters will be needed in multi channel mode
|
|
||||||
```
|
|
||||||
|
|
||||||
See the examples for further reference
|
|
||||||
|
|
||||||
### 1. Initialize relay channels
|
### 1. Initialize relay channels
|
||||||
|
|
||||||
```c
|
```c
|
||||||
// Define GPIO pins for relay channels
|
// Define GPIO pins for relay channels
|
||||||
const uint8_t gpio_map[] = {4, 5}; // One channel example
|
const gpio_num_t gpio_map[] = {GPIO_NUM_4, GPIO_NUM_5}; // One channel example
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
const uint8_t gpio_map[] = {4, 5, 9, 10, 18, 19}; // Or a 3 channel example
|
|
||||||
const uint8_t gpio_count = sizeof(gpio_map) / sizeof(gpio_map[0]);
|
const uint8_t gpio_count = sizeof(gpio_map) / sizeof(gpio_map[0]);
|
||||||
|
|
||||||
// Create and initialize relay channels
|
// Create and initialize relay channels
|
||||||
@@ -76,138 +59,53 @@ if (ret != ESP_OK) {
|
|||||||
|
|
||||||
### 2. Control relay channels
|
### 2. Control relay channels
|
||||||
|
|
||||||
For single mode:
|
|
||||||
|
|
||||||
```c
|
```c
|
||||||
// Run the channel forward
|
// Run channel 0 forward
|
||||||
relay_chn_run_forward();
|
|
||||||
|
|
||||||
// Run the channel reverse
|
|
||||||
relay_chn_run_reverse();
|
|
||||||
|
|
||||||
// Stop the channel
|
|
||||||
relay_chn_stop();
|
|
||||||
|
|
||||||
// Flip the direction of the channel
|
|
||||||
relay_chn_flip_direction();
|
|
||||||
```
|
|
||||||
|
|
||||||
For multi mode
|
|
||||||
|
|
||||||
```c
|
|
||||||
// Run channel #0 forward
|
|
||||||
relay_chn_run_forward(0);
|
relay_chn_run_forward(0);
|
||||||
// Run all channels forward
|
|
||||||
relay_chn_run_forward(RELAY_CHN_ID_ALL);
|
|
||||||
|
|
||||||
// Run channel #1 reverse
|
// Run channel 0 reverse
|
||||||
relay_chn_run_reverse(1);
|
relay_chn_run_reverse(0);
|
||||||
// Run all channels reverse
|
|
||||||
relay_chn_run_reverse(RELAY_CHN_ID_ALL);
|
|
||||||
|
|
||||||
// Stop channel #1
|
// Stop channel 0
|
||||||
relay_chn_stop(1);
|
relay_chn_stop(0);
|
||||||
// Stop all channels
|
|
||||||
relay_chn_stop(RELAY_CHN_ID_ALL);
|
|
||||||
|
|
||||||
// Flip direction of channel #0
|
// Flip direction of channel 0
|
||||||
relay_chn_flip_direction(0);
|
relay_chn_flip_direction(0);
|
||||||
// Flip direction of all channels
|
|
||||||
relay_chn_flip_direction(RELAY_CHN_ID_ALL);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. Monitor channel state
|
### 3. Monitor channel state
|
||||||
|
|
||||||
For single mode:
|
|
||||||
|
|
||||||
```c
|
```c
|
||||||
// Get channel state
|
// Get channel state
|
||||||
relay_chn_state_t state = relay_chn_get_state();
|
|
||||||
// Get the string representation of the state of the channel
|
|
||||||
char *state_str = relay_chn_get_state_str();
|
|
||||||
|
|
||||||
// Get channel direction
|
|
||||||
relay_chn_direction_t direction = relay_chn_get_direction();
|
|
||||||
|
|
||||||
// Listen to relay channel state changes
|
|
||||||
static void relay_chn_listener(uint8_t chn_id, relay_chn_state_t old_state, relay_chn_state_t new_state) {
|
|
||||||
/* The channel id can be ignored in single mode */
|
|
||||||
/* Handle state changes */
|
|
||||||
}
|
|
||||||
// Register the listener callback
|
|
||||||
relay_chn_register_listener(relay_chn_listener);
|
|
||||||
// Unregister the listener when it is not needed anymore
|
|
||||||
relay_chn_unregister_listener(relay_chn_listener);
|
|
||||||
```
|
|
||||||
|
|
||||||
For multi mode:
|
|
||||||
|
|
||||||
```c
|
|
||||||
// Get channel #0 state
|
|
||||||
relay_chn_state_t state = relay_chn_get_state(0);
|
relay_chn_state_t state = relay_chn_get_state(0);
|
||||||
// Get the string representation of the state of the channel #0
|
|
||||||
char *state_str = relay_chn_get_state_str(0);
|
char *state_str = relay_chn_get_state_str(0);
|
||||||
|
|
||||||
// Get channel #0 direction
|
// Get channel direction
|
||||||
relay_chn_direction_t direction = relay_chn_get_direction(0);
|
relay_chn_direction_t direction = relay_chn_get_direction(0);
|
||||||
|
|
||||||
/* The listener is same for multi mode */
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. Tilting Interface (if enabled)
|
### 4. Tilting Interface (if enabled)
|
||||||
|
|
||||||
For single mode:
|
|
||||||
|
|
||||||
```c
|
```c
|
||||||
// Assuming CONFIG_RELAY_CHN_ENABLE_TILTING is enabled
|
// Assuming CONFIG_RELAY_CHN_ENABLE_TILTING is enabled
|
||||||
|
|
||||||
// Start tilting automatically
|
// Start tilting automatically (channel 0)
|
||||||
relay_chn_tilt_auto();
|
|
||||||
|
|
||||||
// Tilt forward
|
|
||||||
relay_chn_tilt_forward();
|
|
||||||
|
|
||||||
// Tilt reverse
|
|
||||||
relay_chn_tilt_reverse();
|
|
||||||
|
|
||||||
// Stop tilting
|
|
||||||
relay_chn_tilt_stop();
|
|
||||||
|
|
||||||
// Set tilting sensitivity (sensitivity as percentage)
|
|
||||||
relay_chn_tilt_sensitivity_set(90);
|
|
||||||
|
|
||||||
// Get tilting sensitivity (sensitivty as percentage)
|
|
||||||
uint8_t sensitivity = relay_chn_tilt_get_sensitivity();
|
|
||||||
```
|
|
||||||
|
|
||||||
For multi mode:
|
|
||||||
|
|
||||||
```c
|
|
||||||
// Assuming CONFIG_RELAY_CHN_ENABLE_TILTING is enabled
|
|
||||||
|
|
||||||
// Start tilting automatically on channel #0
|
|
||||||
relay_chn_tilt_auto(0);
|
relay_chn_tilt_auto(0);
|
||||||
relay_chn_tilt_auto(RELAY_CHN_ID_ALL); // on all channels
|
|
||||||
|
|
||||||
// Tilt forward on channel #1
|
// Tilt forward (channel 0)
|
||||||
relay_chn_tilt_forward(1);
|
relay_chn_tilt_forward(0);
|
||||||
relay_chn_tilt_forward(RELAY_CHN_ID_ALL);
|
|
||||||
|
|
||||||
// Tilt reverse on channel #2
|
// Tilt reverse (channel 0)
|
||||||
relay_chn_tilt_reverse(2);
|
relay_chn_tilt_reverse(0);
|
||||||
relay_chn_tilt_reverse(RELAY_CHN_ID_ALL);
|
|
||||||
|
|
||||||
// Stop tilting on channel #0
|
// Stop tilting (channel 0)
|
||||||
relay_chn_tilt_stop(0);
|
relay_chn_tilt_stop(0);
|
||||||
relay_chn_tilt_stop(RELAY_CHN_ID_ALL);
|
|
||||||
|
|
||||||
// Set tilting sensitivity (sensitivity as percentage) for channel #0
|
// Set tilting sensitivity (channel 0, sensitivity as percentage)
|
||||||
relay_chn_tilt_sensitivity_set(0, 90);
|
relay_chn_tilt_sensitivity_set(0, 90);
|
||||||
relay_chn_tilt_sensitivity_set(RELAY_CHN_ID_ALL, 90);
|
|
||||||
|
|
||||||
// Get tilting sensitivity (sensitivty as percentage)
|
// Get tilting sensitivity (channel 0, sensitivty as percentage)
|
||||||
uint8_t sensitivity;
|
uint8_t sensitivity = relay_chn_tilt_sensitivity_get(0);
|
||||||
relay_chn_tilt_get_sensitivity(0, &sensitivity, sizeof(sensitivity));
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|||||||
@@ -1,8 +1,16 @@
|
|||||||
/*
|
#ifndef RELAY_CHN_H
|
||||||
* SPDX-FileCopyrightText: 2025 Kozmotronik Tech
|
#define RELAY_CHN_H
|
||||||
|
/**
|
||||||
|
* @file relay_chn.h
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* @author
|
||||||
|
* Ismail Sahillioglu <ismailsahillioglu@gmail.com>
|
||||||
*
|
*
|
||||||
|
* @date 2025.02.08
|
||||||
|
*
|
||||||
|
* @defgroup relay_chn Relay Channel Controller
|
||||||
|
* @ingroup components
|
||||||
|
* @{
|
||||||
* One relay channel consists of 2 output relays, hence 2 GPIO pins are required for each relay channel.
|
* One relay channel consists of 2 output relays, hence 2 GPIO pins are required for each relay channel.
|
||||||
* This module provides an API to control the relay channels, specifically to drive bipolar motors.
|
* This module provides an API to control the relay channels, specifically to drive bipolar motors.
|
||||||
* It also provides APIs to control the direction of the relay channel, bipolar motors in mind.
|
* It also provides APIs to control the direction of the relay channel, bipolar motors in mind.
|
||||||
@@ -14,17 +22,66 @@
|
|||||||
* reliability and prevent conflict operations. Also, the esp timer is used to manage the direction change inertia.
|
* reliability and prevent conflict operations. Also, the esp timer is used to manage the direction change inertia.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "relay_chn_defs.h"
|
#include "driver/gpio.h"
|
||||||
#include "relay_chn_types.h"
|
#include <stdint.h>
|
||||||
#include "relay_chn_adapter.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define RELAY_CHN_ID_ALL CONFIG_RELAY_CHN_COUNT ///< Special ID to address all channels
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enumeration for relay channel direction.
|
||||||
|
*/
|
||||||
|
enum relay_chn_direction_enum {
|
||||||
|
RELAY_CHN_DIRECTION_DEFAULT, ///< Default direction of the relay channel.
|
||||||
|
RELAY_CHN_DIRECTION_FLIPPED ///< Flipped direction of the relay channel.
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Alias for the enum type relay_chn_direction_enum.
|
||||||
|
*/
|
||||||
|
typedef enum relay_chn_direction_enum relay_chn_direction_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enums that represent the state of a relay channel.
|
||||||
|
*/
|
||||||
|
enum relay_chn_state_enum {
|
||||||
|
RELAY_CHN_STATE_UNDEFINED, ///< The relay channel state is undefined.
|
||||||
|
RELAY_CHN_STATE_FREE, ///< The relay channel is free to run or execute commands.
|
||||||
|
RELAY_CHN_STATE_STOPPED, ///< The relay channel is stopped and not running.
|
||||||
|
RELAY_CHN_STATE_FORWARD, ///< The relay channel is running in the forward direction.
|
||||||
|
RELAY_CHN_STATE_REVERSE, ///< The relay channel is running in the reverse direction.
|
||||||
|
RELAY_CHN_STATE_FORWARD_PENDING, ///< The relay channel is pending to run in the forward direction.
|
||||||
|
RELAY_CHN_STATE_REVERSE_PENDING, ///< The relay channel is pending to run in the reverse direction.
|
||||||
|
#if CONFIG_RELAY_CHN_ENABLE_TILTING == 1
|
||||||
|
RELAY_CHN_STATE_TILT_FORWARD, ///< The relay channel is tilting for forward.
|
||||||
|
RELAY_CHN_STATE_TILT_REVERSE, ///< The relay channel is tilting for reverse.
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Alias for the enum type relay_chn_state_enum.
|
||||||
|
*/
|
||||||
|
typedef enum relay_chn_state_enum relay_chn_state_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Relay channel state change listener.
|
||||||
|
*
|
||||||
|
* An optional interface to listen to the channel state change events.
|
||||||
|
* The listeners SHOULD be implemented as light functions and SHOULD NOT contain
|
||||||
|
* any blocking calls. Otherwise the relay_chn module would not function properly
|
||||||
|
* since it is designed as event driven.
|
||||||
|
*
|
||||||
|
* @param chn_id The ID of the channel whose state has changed.
|
||||||
|
* @param old_state The old state of the channel.
|
||||||
|
* @param new_state The new state of the channel.
|
||||||
|
*/
|
||||||
|
typedef void (*relay_chn_state_listener_t)(uint8_t chn_id, relay_chn_state_t old_state, relay_chn_state_t new_state);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create and initialize relay channels.
|
* @brief Create and initialize relay channels.
|
||||||
*
|
*
|
||||||
@@ -38,7 +95,7 @@ extern "C" {
|
|||||||
* - ESP_ERR_INVALID_ARG: Invalid argument
|
* - ESP_ERR_INVALID_ARG: Invalid argument
|
||||||
* - ESP_FAIL: General failure
|
* - ESP_FAIL: General failure
|
||||||
*/
|
*/
|
||||||
esp_err_t relay_chn_create(const uint8_t* gpio_map, uint8_t gpio_count);
|
esp_err_t relay_chn_create(const gpio_num_t* gpio_map, uint8_t gpio_count);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Destroy the relay channels and free resources.
|
* @brief Destroy the relay channels and free resources.
|
||||||
@@ -67,7 +124,6 @@ esp_err_t relay_chn_register_listener(relay_chn_state_listener_t listener);
|
|||||||
*/
|
*/
|
||||||
void relay_chn_unregister_listener(relay_chn_state_listener_t listener);
|
void relay_chn_unregister_listener(relay_chn_state_listener_t listener);
|
||||||
|
|
||||||
#if RELAY_CHN_COUNT > 1
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the state of the specified relay channel.
|
* @brief Get the state of the specified relay channel.
|
||||||
*
|
*
|
||||||
@@ -94,6 +150,14 @@ relay_chn_state_t relay_chn_get_state(uint8_t chn_id);
|
|||||||
*/
|
*/
|
||||||
char *relay_chn_get_state_str(uint8_t chn_id);
|
char *relay_chn_get_state_str(uint8_t chn_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return the text presentation of an state.
|
||||||
|
*
|
||||||
|
* @param state A state with type of relay_chn_state_t.
|
||||||
|
* @return char* The text presentation of the state. "UNKNOWN" if the state is not known.
|
||||||
|
*/
|
||||||
|
char *relay_chn_state_str(relay_chn_state_t state);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Runs the relay channel in the forward direction.
|
* @brief Runs the relay channel in the forward direction.
|
||||||
*
|
*
|
||||||
@@ -127,7 +191,8 @@ void relay_chn_stop(uint8_t chn_id);
|
|||||||
* @brief Flips the direction of the specified relay channel.
|
* @brief Flips the direction of the specified relay channel.
|
||||||
*
|
*
|
||||||
* This function toggles the direction of the relay channel identified by the
|
* This function toggles the direction of the relay channel identified by the
|
||||||
* given channel ID.
|
* given channel ID. It is typically used to change the state of the relay
|
||||||
|
* from its current direction to the opposite direction.
|
||||||
*
|
*
|
||||||
* @param chn_id The ID of the relay channel to flip. This should be a valid
|
* @param chn_id The ID of the relay channel to flip. This should be a valid
|
||||||
* channel ID within the range of available relay channels.
|
* channel ID within the range of available relay channels.
|
||||||
@@ -152,9 +217,9 @@ relay_chn_direction_t relay_chn_get_direction(uint8_t chn_id);
|
|||||||
/**
|
/**
|
||||||
* @brief Enables automatic tilting for the specified relay channel.
|
* @brief Enables automatic tilting for the specified relay channel.
|
||||||
*
|
*
|
||||||
* This function enables automatic tilting mode for the given relay channel.
|
* This function enables automatic tilting mode for the given relay channel. The channel will automatically
|
||||||
* The channel will automatically switch between forward and reverse tilting
|
* switch between forward and reverse tilting based on some internal sensing mechanism (not detailed here).
|
||||||
* based on the last movement of the channel
|
* Requires appropriate hardware support and configuration.
|
||||||
*
|
*
|
||||||
* @param chn_id The ID of the relay channel to enable automatic tilting.
|
* @param chn_id The ID of the relay channel to enable automatic tilting.
|
||||||
*/
|
*/
|
||||||
@@ -163,7 +228,8 @@ void relay_chn_tilt_auto(uint8_t chn_id);
|
|||||||
/**
|
/**
|
||||||
* @brief Tilts the specified relay channel forward.
|
* @brief Tilts the specified relay channel forward.
|
||||||
*
|
*
|
||||||
* This function initiates a forward tilting action for the specified relay channel.
|
* This function initiates a forward tilting action for the specified relay channel. This is a manual tilting
|
||||||
|
* operation, unlike `relay_chn_tilt_auto()`.
|
||||||
*
|
*
|
||||||
* @param chn_id The ID of the relay channel to tilt forward.
|
* @param chn_id The ID of the relay channel to tilt forward.
|
||||||
*/
|
*/
|
||||||
@@ -172,7 +238,8 @@ void relay_chn_tilt_forward(uint8_t chn_id);
|
|||||||
/**
|
/**
|
||||||
* @brief Tilts the specified relay channel reverse.
|
* @brief Tilts the specified relay channel reverse.
|
||||||
*
|
*
|
||||||
* This function initiates a reverse tilting action for the specified relay channel.
|
* This function initiates a reverse tilting action for the specified relay channel. This is a manual tilting
|
||||||
|
* operation, unlike `relay_chn_tilt_auto()`.
|
||||||
*
|
*
|
||||||
* @param chn_id The ID of the relay channel to tilt reverse.
|
* @param chn_id The ID of the relay channel to tilt reverse.
|
||||||
*/
|
*/
|
||||||
@@ -196,7 +263,7 @@ void relay_chn_tilt_stop(uint8_t chn_id);
|
|||||||
* @param chn_id The ID of the relay channel to set the sensitivity for.
|
* @param chn_id The ID of the relay channel to set the sensitivity for.
|
||||||
* @param sensitivity The sensitivity in percentage: 0 - 100%.
|
* @param sensitivity The sensitivity in percentage: 0 - 100%.
|
||||||
*/
|
*/
|
||||||
void relay_chn_tilt_set_sensitivity(uint8_t chn_id, uint8_t sensitivity);
|
void relay_chn_tilt_sensitivity_set(uint8_t chn_id, uint8_t sensitivity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the tilting sensitivity for the specified relay channel.
|
* @brief Gets the tilting sensitivity for the specified relay channel.
|
||||||
@@ -211,127 +278,14 @@ void relay_chn_tilt_set_sensitivity(uint8_t chn_id, uint8_t sensitivity);
|
|||||||
* - ESP_OK: Success
|
* - ESP_OK: Success
|
||||||
* - ESP_ERR_INVALID_ARG: Invalid argument
|
* - ESP_ERR_INVALID_ARG: Invalid argument
|
||||||
*/
|
*/
|
||||||
esp_err_t relay_chn_tilt_get_sensitivity(uint8_t chn_id, uint8_t *sensitivity, size_t length);
|
esp_err_t relay_chn_tilt_sensitivity_get(uint8_t chn_id, uint8_t *sensitivity, size_t length);
|
||||||
|
|
||||||
#endif // CONFIG_RELAY_CHN_ENABLE_TILTING
|
#endif // CONFIG_RELAY_CHN_ENABLE_TILTING
|
||||||
|
|
||||||
#else // RELAY_CHN_COUNT > 1
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the state of the relay channel.
|
|
||||||
*
|
|
||||||
* This function retrieves the current state of the relay channel.
|
|
||||||
*
|
|
||||||
* @return The current state of the relay channel.
|
|
||||||
*/
|
|
||||||
relay_chn_state_t relay_chn_get_state(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the state string of the relay channel.
|
|
||||||
*
|
|
||||||
* This function returns a string representation of the state of the relay channel.
|
|
||||||
*
|
|
||||||
* @return A pointer to a string representing the state of the relay
|
|
||||||
* channel. The returned string is managed internally and should not be
|
|
||||||
* modified or freed by the caller.
|
|
||||||
*/
|
|
||||||
char *relay_chn_get_state_str(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Runs the relay channel in the forward direction.
|
|
||||||
*
|
|
||||||
* This function activates the relay channel to run in the forward direction.
|
|
||||||
*/
|
|
||||||
void relay_chn_run_forward(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Runs the relay channel in reverse.
|
|
||||||
*
|
|
||||||
* This function activates the relay channel to run in reverse.
|
|
||||||
*/
|
|
||||||
void relay_chn_run_reverse(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Stops the relay channel.
|
|
||||||
*
|
|
||||||
* This function stops the operation of the relay channel.
|
|
||||||
*/
|
|
||||||
void relay_chn_stop(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Flips the direction of the relay channel.
|
|
||||||
*
|
|
||||||
* This function toggles the direction of the relay channel.
|
|
||||||
*/
|
|
||||||
void relay_chn_flip_direction(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the direction of the relay channel.
|
|
||||||
*
|
|
||||||
* This function retrieves the direction configuration of a relay channel.
|
|
||||||
*
|
|
||||||
* @return The direction of the relay channel as a value of type
|
|
||||||
* relay_chn_direction_t.
|
|
||||||
*/
|
|
||||||
relay_chn_direction_t relay_chn_get_direction(void);
|
|
||||||
|
|
||||||
|
|
||||||
#if CONFIG_RELAY_CHN_ENABLE_TILTING == 1
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Enables automatic tilting for the relay channel.
|
|
||||||
*
|
|
||||||
* This function enables automatic tilting mode for the given relay channel.
|
|
||||||
* The channel will automatically switch between forward and reverse tilting
|
|
||||||
* based on the last movement of the channel
|
|
||||||
*/
|
|
||||||
void relay_chn_tilt_auto(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Tilts the relay channel forward.
|
|
||||||
*
|
|
||||||
* This function initiates a forward tilting action for the relay channel.
|
|
||||||
*/
|
|
||||||
void relay_chn_tilt_forward(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Tilts the relay channel reverse.
|
|
||||||
*
|
|
||||||
* This function initiates a reverse tilting action for the relay channel.
|
|
||||||
*/
|
|
||||||
void relay_chn_tilt_reverse(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Stops the tilting action on the relay channel.
|
|
||||||
*
|
|
||||||
* This function stops any ongoing tilting action (automatic or manual) on the relay channel.
|
|
||||||
*/
|
|
||||||
void relay_chn_tilt_stop(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Sets the tilting sensitivity for the relay channel.
|
|
||||||
*
|
|
||||||
* This function sets the sensitivity for the automatic tilting mechanism. A higher sensitivity value
|
|
||||||
* typically means the channel will react more readily to tilting events.
|
|
||||||
*
|
|
||||||
* @param sensitivity The sensitivity in percentage: 0 - 100%.
|
|
||||||
*/
|
|
||||||
void relay_chn_tilt_set_sensitivity(uint8_t sensitivity);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Gets the tilting sensitivity for the relay channel.
|
|
||||||
*
|
|
||||||
* This function retrieves the currently set sensitivity for the relay channel's automatic
|
|
||||||
* tilting mechanism.
|
|
||||||
*
|
|
||||||
* @return Sensitivity value in percentage: 0 - 100%.
|
|
||||||
*/
|
|
||||||
uint8_t relay_chn_tilt_get_sensitivity(void);
|
|
||||||
|
|
||||||
#endif // CONFIG_RELAY_CHN_ENABLE_TILTING
|
|
||||||
|
|
||||||
#endif // RELAY_CHN_COUNT > 1
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
#endif // RELAY_CHN_H
|
||||||
@@ -1,186 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2025 Kozmotronik Tech
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*
|
|
||||||
* An adapter header to expose the appropriate API functions to the public API
|
|
||||||
* depending on the RELAY_CHN_COUNT value which determines single or multi mode.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if RELAY_CHN_COUNT > 1
|
|
||||||
/**
|
|
||||||
* @brief Get the current state of a relay channel.
|
|
||||||
*
|
|
||||||
* @param[in] chn_id Channel ID to get state for.
|
|
||||||
* @return Current state of the specified channel, or RELAY_CHN_STATE_UNDEFINED if invalid.
|
|
||||||
*/
|
|
||||||
extern relay_chn_state_t relay_chn_ctl_get_state(uint8_t chn_id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get string representation of a relay channel's state.
|
|
||||||
*
|
|
||||||
* @param[in] chn_id Channel ID to get state string for.
|
|
||||||
* @return String representation of channel state, or "UNDEFINED" if invalid.
|
|
||||||
*/
|
|
||||||
extern char *relay_chn_ctl_get_state_str(uint8_t chn_id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Run a relay channel in forward direction.
|
|
||||||
*
|
|
||||||
* @param[in] chn_id Channel ID to run forward, or RELAY_CHN_ID_ALL for all channels.
|
|
||||||
*/
|
|
||||||
extern void relay_chn_ctl_run_forward(uint8_t chn_id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Run a relay channel in reverse direction.
|
|
||||||
*
|
|
||||||
* @param[in] chn_id Channel ID to run reverse, or RELAY_CHN_ID_ALL for all channels.
|
|
||||||
*/
|
|
||||||
extern void relay_chn_ctl_run_reverse(uint8_t chn_id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Stop a relay channel.
|
|
||||||
*
|
|
||||||
* @param[in] chn_id Channel ID to stop, or RELAY_CHN_ID_ALL for all channels.
|
|
||||||
*/
|
|
||||||
extern void relay_chn_ctl_stop(uint8_t chn_id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Flip the running direction of a relay channel.
|
|
||||||
*
|
|
||||||
* @param[in] chn_id Channel ID to flip direction for, or RELAY_CHN_ID_ALL for all channels.
|
|
||||||
*/
|
|
||||||
extern void relay_chn_ctl_flip_direction(uint8_t chn_id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the current direction of a relay channel.
|
|
||||||
*
|
|
||||||
* @param[in] chn_id Channel ID to get direction for.
|
|
||||||
* @return Current direction of the specified channel, or RELAY_CHN_DIRECTION_DEFAULT if invalid.
|
|
||||||
*/
|
|
||||||
extern relay_chn_direction_t relay_chn_ctl_get_direction(uint8_t chn_id);
|
|
||||||
|
|
||||||
static inline relay_chn_state_t relay_chn_get_state(uint8_t chn_id)
|
|
||||||
{
|
|
||||||
return relay_chn_ctl_get_state(chn_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline char *relay_chn_get_state_str(uint8_t chn_id)
|
|
||||||
{
|
|
||||||
return relay_chn_ctl_get_state_str(chn_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void relay_chn_run_forward(uint8_t chn_id)
|
|
||||||
{
|
|
||||||
relay_chn_ctl_run_forward(chn_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void relay_chn_run_reverse(uint8_t chn_id)
|
|
||||||
{
|
|
||||||
relay_chn_ctl_run_reverse(chn_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void relay_chn_stop(uint8_t chn_id)
|
|
||||||
{
|
|
||||||
relay_chn_ctl_stop(chn_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void relay_chn_flip_direction(uint8_t chn_id)
|
|
||||||
{
|
|
||||||
relay_chn_ctl_flip_direction(chn_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline relay_chn_direction_t relay_chn_get_direction(uint8_t chn_id)
|
|
||||||
{
|
|
||||||
return relay_chn_ctl_get_direction(chn_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the current state of the relay channel.
|
|
||||||
*
|
|
||||||
* @return Current state of the channel.
|
|
||||||
*/
|
|
||||||
extern relay_chn_state_t relay_chn_ctl_get_state(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get string representation of the relay channel's state.
|
|
||||||
*
|
|
||||||
* @return String representation of channel state.
|
|
||||||
*/
|
|
||||||
extern char *relay_chn_ctl_get_state_str(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Run the relay channel in forward direction.
|
|
||||||
*/
|
|
||||||
extern void relay_chn_ctl_run_forward(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Run the relay channel in reverse direction.
|
|
||||||
*/
|
|
||||||
extern void relay_chn_ctl_run_reverse(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Stop the relay channel.
|
|
||||||
*/
|
|
||||||
extern void relay_chn_ctl_stop(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Flip the running direction of the relay channel.
|
|
||||||
*/
|
|
||||||
extern void relay_chn_ctl_flip_direction(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the current direction of the relay channel.
|
|
||||||
*
|
|
||||||
* @return Current direction of the channel.
|
|
||||||
*/
|
|
||||||
extern relay_chn_direction_t relay_chn_ctl_get_direction(void);
|
|
||||||
|
|
||||||
static inline relay_chn_state_t relay_chn_get_state(void)
|
|
||||||
{
|
|
||||||
return relay_chn_ctl_get_state();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline char *relay_chn_get_state_str(void)
|
|
||||||
{
|
|
||||||
return relay_chn_ctl_get_state_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void relay_chn_run_forward(void)
|
|
||||||
{
|
|
||||||
relay_chn_ctl_run_forward();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void relay_chn_run_reverse(void)
|
|
||||||
{
|
|
||||||
relay_chn_ctl_run_reverse();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void relay_chn_stop(void)
|
|
||||||
{
|
|
||||||
relay_chn_ctl_stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void relay_chn_flip_direction(void)
|
|
||||||
{
|
|
||||||
relay_chn_ctl_flip_direction();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline relay_chn_direction_t relay_chn_get_direction(void)
|
|
||||||
{
|
|
||||||
return relay_chn_ctl_get_direction();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // RELAY_CHN_COUNT > 1
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2025 Kozmotronik Tech
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Config defines for covenient writing */
|
|
||||||
#define RELAY_CHN_OPPOSITE_INERTIA_MS CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS
|
|
||||||
#define RELAY_CHN_COUNT CONFIG_RELAY_CHN_COUNT
|
|
||||||
#define RELAY_CHN_ENABLE_TILTING CONFIG_RELAY_CHN_ENABLE_TILTING
|
|
||||||
|
|
||||||
#if RELAY_CHN_COUNT > 1
|
|
||||||
#define RELAY_CHN_ID_ALL RELAY_CHN_COUNT /*!< Special ID to address all channels */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2025 Kozmotronik Tech
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "relay_chn_defs.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Enumeration for relay channel direction.
|
|
||||||
*/
|
|
||||||
typedef enum relay_chn_direction_enum {
|
|
||||||
RELAY_CHN_DIRECTION_DEFAULT, /*!< Default direction of the relay channel */
|
|
||||||
RELAY_CHN_DIRECTION_FLIPPED /*!< Flipped direction of the relay channel */
|
|
||||||
} relay_chn_direction_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Enums that represent the state of a relay channel.
|
|
||||||
*/
|
|
||||||
typedef enum relay_chn_state_enum {
|
|
||||||
RELAY_CHN_STATE_UNDEFINED, /*!< The relay channel state is undefined */
|
|
||||||
RELAY_CHN_STATE_IDLE, /*!< The relay channel is free to run or execute commands */
|
|
||||||
RELAY_CHN_STATE_STOPPED, /*!< The relay channel is stopped and not running */
|
|
||||||
RELAY_CHN_STATE_FORWARD, /*!< The relay channel is running in the forward direction */
|
|
||||||
RELAY_CHN_STATE_REVERSE, /*!< The relay channel is running in the reverse direction */
|
|
||||||
RELAY_CHN_STATE_FORWARD_PENDING, /*!< The relay channel is pending to run in the forward direction */
|
|
||||||
RELAY_CHN_STATE_REVERSE_PENDING, /*!< The relay channel is pending to run in the reverse direction */
|
|
||||||
#if CONFIG_RELAY_CHN_ENABLE_TILTING == 1
|
|
||||||
RELAY_CHN_STATE_TILT_FORWARD, /*!< The relay channel is tilting for forward */
|
|
||||||
RELAY_CHN_STATE_TILT_REVERSE, /*!< The relay channel is tilting for reverse */
|
|
||||||
#endif
|
|
||||||
} relay_chn_state_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Relay channel state change listener.
|
|
||||||
*
|
|
||||||
* An optional interface to listen to the channel state change events.
|
|
||||||
* The listeners SHOULD be implemented as light functions and SHOULD NOT contain
|
|
||||||
* any blocking calls. Otherwise the relay_chn module would not function properly
|
|
||||||
* since it is designed as event driven.
|
|
||||||
*
|
|
||||||
* @param chn_id The ID of the channel whose state has changed.
|
|
||||||
* @param old_state The old state of the channel.
|
|
||||||
* @param new_state The new state of the channel.
|
|
||||||
*/
|
|
||||||
typedef void (*relay_chn_state_listener_t)(uint8_t chn_id, relay_chn_state_t old_state, relay_chn_state_t new_state);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2025 Kozmotronik Tech
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "esp_err.h"
|
|
||||||
#include "esp_log.h"
|
|
||||||
#include "esp_event_base.h"
|
|
||||||
#include "esp_event.h"
|
|
||||||
#include "esp_timer.h"
|
|
||||||
#include "relay_chn_defs.h"
|
|
||||||
#include "relay_chn_types.h"
|
|
||||||
#include "relay_chn_priv_types.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Event base used by *_core, *_ctl, and *_tilt modules.
|
|
||||||
ESP_EVENT_DECLARE_BASE(RELAY_CHN_CMD_EVENT);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initializes the relay channel timer.
|
|
||||||
*
|
|
||||||
* This function creates a timer for the relay channel to handle direction change inertia.
|
|
||||||
* Required by *_ctl_* module.
|
|
||||||
*
|
|
||||||
* @param chn_ctl Pointer to the relay channel control structure.
|
|
||||||
* @return esp_err_t ESP_OK on success, or an error code on failure.
|
|
||||||
*/
|
|
||||||
esp_err_t relay_chn_init_timer(relay_chn_ctl_t *chn_ctl);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Issues a command to the relay channel.
|
|
||||||
*
|
|
||||||
* Evaluates the current state of the relay channel and issues the command accordingly.
|
|
||||||
* Required by *_core, *_ctl_* and *_tilt modules.
|
|
||||||
*
|
|
||||||
* @param chn_ctl Pointer to the relay channel control structure.
|
|
||||||
* @param cmd The command to issue.
|
|
||||||
*/
|
|
||||||
void relay_chn_issue_cmd(relay_chn_ctl_t* chn_ctl, relay_chn_cmd_t cmd);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Dispatches a relay channel command to the event loop.
|
|
||||||
*
|
|
||||||
* @param chn_ctl Pointer to the relay channel control structure.
|
|
||||||
* @param cmd The command to dispatch.
|
|
||||||
*/
|
|
||||||
void relay_chn_dispatch_cmd(relay_chn_ctl_t *chn_ctl, relay_chn_cmd_t cmd);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns the string representation of a relay channel command.
|
|
||||||
*
|
|
||||||
* @param cmd The relay channel command.
|
|
||||||
* @return char* The string representation of the command.
|
|
||||||
*/
|
|
||||||
char *relay_chn_cmd_str(relay_chn_cmd_t cmd);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Starts the ESP timer once with the specified time in milliseconds.
|
|
||||||
*
|
|
||||||
* Starts the ESP timer to run once after the specified time.
|
|
||||||
* If the timer is already running, it stops it first and then starts it again.
|
|
||||||
* Required by *_ctl_* and *_tilt modules.
|
|
||||||
*
|
|
||||||
* @param esp_timer The ESP timer handle.
|
|
||||||
* @param time_ms The time in milliseconds to wait before the timer expires.
|
|
||||||
* @return esp_err_t ESP_OK on success, or an error code on failure.
|
|
||||||
*/
|
|
||||||
esp_err_t relay_chn_start_esp_timer_once(esp_timer_handle_t esp_timer, uint32_t time_ms);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Updates the state of the relay channel and notifies listeners.
|
|
||||||
*
|
|
||||||
* This function updates the state of the relay channel and notifies all registered listeners
|
|
||||||
* about the state change.
|
|
||||||
* Required by *_ctl_* and *_tilt modules.
|
|
||||||
*
|
|
||||||
* @param chn_ctl Pointer to the relay channel control structure.
|
|
||||||
* @param new_state The new state to set for the relay channel.
|
|
||||||
*/
|
|
||||||
void relay_chn_update_state(relay_chn_ctl_t *chn_ctl, relay_chn_state_t new_state);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Return the text presentation of an state.
|
|
||||||
*
|
|
||||||
* @param state A state with type of relay_chn_state_t.
|
|
||||||
* @return char* The text presentation of the state. "UNKNOWN" if the state is not known.
|
|
||||||
*/
|
|
||||||
char *relay_chn_state_str(relay_chn_state_t state);
|
|
||||||
|
|
||||||
#if RELAY_CHN_COUNT > 1
|
|
||||||
/**
|
|
||||||
* @brief Check if the provided channel ID is valid.
|
|
||||||
*
|
|
||||||
* @param chn_id Channel ID to check.
|
|
||||||
* @return true Channel ID is valid.
|
|
||||||
* @return false Channel ID is invalid.
|
|
||||||
*/
|
|
||||||
bool relay_chn_is_channel_id_valid(uint8_t chn_id);
|
|
||||||
#endif // RELAY_CHN_COUNT > 1
|
|
||||||
|
|
||||||
#if RELAY_CHN_ENABLE_TILTING == 1
|
|
||||||
/// Relay channel event loop handle declaration for *_tilt module.
|
|
||||||
extern esp_event_loop_handle_t relay_chn_event_loop;
|
|
||||||
#endif // RELAY_CHN_ENABLE_TILTING
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2025 Kozmotronik Tech developer@kozmotronik.com.tr
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*
|
|
||||||
* Expose the *_ctl functions required by *_core.c file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "relay_chn_priv_types.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize the relay channel control.
|
|
||||||
*
|
|
||||||
* @param output Pointer to the output object(s).
|
|
||||||
* @param run_info Pointer to the runtime information object(s).
|
|
||||||
*
|
|
||||||
* @return esp_err_t Returns ESP_OK on success, or an error code on failure.
|
|
||||||
*/
|
|
||||||
esp_err_t relay_chn_ctl_init(relay_chn_output_t *output, relay_chn_run_info_t *run_info);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Deinitialize the relay channel control.
|
|
||||||
*
|
|
||||||
* This function cleans up resources used by the relay channel control.
|
|
||||||
*/
|
|
||||||
void relay_chn_ctl_deinit(void);
|
|
||||||
|
|
||||||
#if RELAY_CHN_COUNT > 1
|
|
||||||
/**
|
|
||||||
* @brief Get the control structure for a specific relay channel.
|
|
||||||
*
|
|
||||||
* @param chn_id The ID of the relay channel to retrieve.
|
|
||||||
*
|
|
||||||
* @return relay_chn_ctl_t* Pointer to the control structure for the specified channel, or NULL if not found.
|
|
||||||
*/
|
|
||||||
relay_chn_ctl_t *relay_chn_ctl_get(uint8_t chn_id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the control structures for all relay channels.
|
|
||||||
*
|
|
||||||
* @return relay_chn_ctl_t* Pointer to the array of control structures for all channels.
|
|
||||||
*/
|
|
||||||
relay_chn_ctl_t *relay_chn_ctl_get_all(void);
|
|
||||||
#else
|
|
||||||
relay_chn_ctl_t *relay_chn_ctl_get(void);
|
|
||||||
#endif // RELAY_CHN_COUNT > 1
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2025 Kozmotronik Tech
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*
|
|
||||||
* Abstraction layer for controlling relay channel outputs. This is the layer
|
|
||||||
* that interacts with the GPIO pins to control the relay channels.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "esp_err.h"
|
|
||||||
#include "relay_chn_priv_types.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize relay channel outputs.
|
|
||||||
*
|
|
||||||
* Maps relay channels to GPIO pins and prepares them for operation.
|
|
||||||
*
|
|
||||||
* @param[in] gpio_map Array of GPIO pin numbers for each relay channel.
|
|
||||||
* @param[in] gpio_count Number of GPIO pins (relay channels).
|
|
||||||
*
|
|
||||||
* @return ESP_OK on success, error code otherwise.
|
|
||||||
*/
|
|
||||||
esp_err_t relay_chn_output_init(const uint8_t* gpio_map, uint8_t gpio_count);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Deinitialize relay channel outputs.
|
|
||||||
*
|
|
||||||
* Releases resources and resets GPIO pins used for relay channels.
|
|
||||||
*/
|
|
||||||
void relay_chn_output_deinit(void);
|
|
||||||
|
|
||||||
#if RELAY_CHN_COUNT > 1
|
|
||||||
/**
|
|
||||||
* @brief Get the relay channel output object for a specific channel.
|
|
||||||
*
|
|
||||||
* @param[in] chn_id Channel ID.
|
|
||||||
*
|
|
||||||
* @return Pointer to relay channel output object, or NULL if invalid.
|
|
||||||
*/
|
|
||||||
relay_chn_output_t *relay_chn_output_get(uint8_t chn_id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get all relay channel output objects.
|
|
||||||
*
|
|
||||||
* @return Pointer to array of relay channel output objects.
|
|
||||||
*/
|
|
||||||
relay_chn_output_t *relay_chn_output_get_all(void);
|
|
||||||
#else
|
|
||||||
/**
|
|
||||||
* @brief Get the relay channel output object.
|
|
||||||
*
|
|
||||||
* @return Pointer to relay channel output object.
|
|
||||||
*/
|
|
||||||
relay_chn_output_t *relay_chn_output_get(void);
|
|
||||||
#endif // RELAY_CHN_COUNT > 1
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Stop the relay channel output.
|
|
||||||
*
|
|
||||||
* Sets the relay channel to the stop state.
|
|
||||||
*
|
|
||||||
* @param[in] output Pointer to relay channel output object.
|
|
||||||
*
|
|
||||||
* @return ESP_OK on success, error code otherwise.
|
|
||||||
*/
|
|
||||||
esp_err_t relay_chn_output_stop(relay_chn_output_t *output);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set relay channel output to forward direction.
|
|
||||||
*
|
|
||||||
* @param[in] output Pointer to relay channel output object.
|
|
||||||
*
|
|
||||||
* @return ESP_OK on success, error code otherwise.
|
|
||||||
*/
|
|
||||||
esp_err_t relay_chn_output_forward(relay_chn_output_t *output);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set relay channel output to reverse direction.
|
|
||||||
*
|
|
||||||
* @param[in] output Pointer to relay channel output object.
|
|
||||||
*
|
|
||||||
* @return ESP_OK on success, error code otherwise.
|
|
||||||
*/
|
|
||||||
esp_err_t relay_chn_output_reverse(relay_chn_output_t *output);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Flip the direction of the relay channel output.
|
|
||||||
*
|
|
||||||
* Changes the direction from forward to reverse or vice versa.
|
|
||||||
*
|
|
||||||
* @param[in] output Pointer to relay channel output object.
|
|
||||||
*/
|
|
||||||
void relay_chn_output_flip(relay_chn_output_t *output);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the current direction of the relay channel output.
|
|
||||||
*
|
|
||||||
* @param[in] output Pointer to relay channel output object.
|
|
||||||
*
|
|
||||||
* @return Current direction of the relay channel.
|
|
||||||
*/
|
|
||||||
relay_chn_direction_t relay_chn_output_get_direction(relay_chn_output_t *output);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2025 Kozmotronik Tech
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "driver/gpio.h"
|
|
||||||
#include "esp_timer.h"
|
|
||||||
#include "relay_chn_types.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Enumeration for relay channel commands.
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
RELAY_CHN_CMD_NONE, /*!< No command */
|
|
||||||
RELAY_CHN_CMD_STOP, /*!< Stop the relay channel */
|
|
||||||
RELAY_CHN_CMD_FORWARD, /*!< Run the relay channel in the forward direction */
|
|
||||||
RELAY_CHN_CMD_REVERSE, /*!< Run the relay channel in the reverse direction */
|
|
||||||
RELAY_CHN_CMD_FLIP, /*!< Flip the direction of the relay channel */
|
|
||||||
RELAY_CHN_CMD_IDLE /*!< Free the relay channel */
|
|
||||||
} relay_chn_cmd_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Structure to hold the output configuration of a relay channel.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
gpio_num_t forward_pin; /*!< GPIO pin number for the forward direction */
|
|
||||||
gpio_num_t reverse_pin; /*!< GPIO pin number for the reverse direction */
|
|
||||||
relay_chn_direction_t direction; /*!< The current direction of the relay channel */
|
|
||||||
} relay_chn_output_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Structure to hold runtime information for a relay channel.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
relay_chn_cmd_t last_run_cmd; /*!< The last run command issued on the relay channel; forward or reverse */
|
|
||||||
uint32_t last_run_cmd_time_ms; /*!< The time in milliseconds when the last run command was issued */
|
|
||||||
} relay_chn_run_info_t;
|
|
||||||
|
|
||||||
#if RELAY_CHN_ENABLE_TILTING == 1
|
|
||||||
/// @brief Tilt commands.
|
|
||||||
typedef enum {
|
|
||||||
RELAY_CHN_TILT_CMD_NONE, /*!< No command */
|
|
||||||
RELAY_CHN_TILT_CMD_STOP, /*!< Tilt command stop */
|
|
||||||
RELAY_CHN_TILT_CMD_FORWARD, /*!< Tilt command for forward */
|
|
||||||
RELAY_CHN_TILT_CMD_REVERSE /*!< Tilt command for reverse */
|
|
||||||
} relay_chn_tilt_cmd_t;
|
|
||||||
|
|
||||||
/// Forward declaration for relay_chn_tilt_ctl
|
|
||||||
typedef struct relay_chn_tilt_ctl relay_chn_tilt_ctl_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Structure to hold the state and configuration of a relay channel.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
uint8_t id; /*!< The ID of the relay channel */
|
|
||||||
relay_chn_state_t state; /*!< The current state of the relay channel */
|
|
||||||
relay_chn_run_info_t *run_info; /*!< Runtime information of the relay channel */
|
|
||||||
relay_chn_output_t *output; /*!< Output configuration of the relay channel */
|
|
||||||
relay_chn_cmd_t pending_cmd; /*!< The command that is pending to be issued */
|
|
||||||
esp_timer_handle_t inertia_timer; /*!< Timer to handle the opposite direction inertia time */
|
|
||||||
#if RELAY_CHN_ENABLE_TILTING == 1
|
|
||||||
relay_chn_tilt_ctl_t *tilt_ctl; /*!< Pointer to the tilt control structure if tilting is enabled */
|
|
||||||
#endif
|
|
||||||
} relay_chn_ctl_t;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2025 Kozmotronik Tech
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*
|
|
||||||
* This is for managing the run information of relay channels.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "relay_chn_priv_types.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize relay channel run information.
|
|
||||||
*
|
|
||||||
* Initializes the run information for all relay channels with default values.
|
|
||||||
*/
|
|
||||||
void relay_chn_run_info_init(void);
|
|
||||||
|
|
||||||
#if RELAY_CHN_COUNT > 1
|
|
||||||
/**
|
|
||||||
* @brief Get run information object for a specific relay channel.
|
|
||||||
*
|
|
||||||
* @param[in] chn_id Channel ID to get run information for.
|
|
||||||
* @return Pointer to run information structure, or NULL if channel ID is invalid.
|
|
||||||
*/
|
|
||||||
relay_chn_run_info_t *relay_chn_run_info_get(uint8_t chn_id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get run information objects for all relay channels.
|
|
||||||
*
|
|
||||||
* @return Pointer to array of run information structures.
|
|
||||||
*/
|
|
||||||
relay_chn_run_info_t *relay_chn_run_info_get_all(void);
|
|
||||||
#else
|
|
||||||
/**
|
|
||||||
* @brief Get run information object for the single relay channel.
|
|
||||||
*
|
|
||||||
* @return Pointer to run information structure.
|
|
||||||
*/
|
|
||||||
relay_chn_run_info_t *relay_chn_run_info_get(void);
|
|
||||||
#endif // RELAY_CHN_COUNT > 1
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the last run command for a relay channel.
|
|
||||||
*
|
|
||||||
* @param[in] run_info Pointer to run information structure.
|
|
||||||
*
|
|
||||||
* @return Last command that was executed, or RELAY_CHN_CMD_NONE if invalid.
|
|
||||||
*/
|
|
||||||
relay_chn_cmd_t relay_chn_run_info_get_last_run_cmd(relay_chn_run_info_t *run_info);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set the last run command for a relay channel.
|
|
||||||
*
|
|
||||||
* @param[in] run_info Pointer to run information structure.
|
|
||||||
* @param[in] cmd Command to set as last run command.
|
|
||||||
*/
|
|
||||||
void relay_chn_run_info_set_last_run_cmd(relay_chn_run_info_t *run_info, relay_chn_cmd_t cmd);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the timestamp of the last run command.
|
|
||||||
*
|
|
||||||
* @param[in] run_info Pointer to run information structure.
|
|
||||||
*
|
|
||||||
* @return Timestamp in milliseconds of last command, or 0 if invalid.
|
|
||||||
*/
|
|
||||||
uint32_t relay_chn_run_info_get_last_run_cmd_time_ms(relay_chn_run_info_t *run_info);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set the timestamp for the last run command.
|
|
||||||
*
|
|
||||||
* @param[in] run_info Pointer to run information structure.
|
|
||||||
* @param[in] time_ms Timestamp in milliseconds to set.
|
|
||||||
*/
|
|
||||||
void relay_chn_run_info_set_last_run_cmd_time_ms(relay_chn_run_info_t *run_info, uint32_t time_ms);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2025 Kozmotronik Tech
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "relay_chn_priv_types.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize relay channel tilt controls.
|
|
||||||
*
|
|
||||||
* Sets up tilt functionality for relay channels including timers and event handlers.
|
|
||||||
* Must be called before using any other tilt functions.
|
|
||||||
*
|
|
||||||
* @param[in] chn_ctls Array of relay channel control structures.
|
|
||||||
*
|
|
||||||
* @return ESP_OK on success, error code otherwise.
|
|
||||||
*/
|
|
||||||
esp_err_t relay_chn_tilt_init(relay_chn_ctl_t *chn_ctls);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Deinitialize relay channel tilt controls.
|
|
||||||
*
|
|
||||||
* Cleans up tilt resources including timers and event handlers.
|
|
||||||
* Should be called when tilt functionality is no longer needed.
|
|
||||||
*/
|
|
||||||
void relay_chn_tilt_deinit(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Dispatch a tilt command to a relay channel.
|
|
||||||
*
|
|
||||||
* Queues a tilt command for execution on the specified channel.
|
|
||||||
*
|
|
||||||
* @param[in] tilt_ctl Pointer to tilt control structure.
|
|
||||||
* @param[in] cmd Tilt command to execute.
|
|
||||||
*
|
|
||||||
* @return ESP_OK on success, error code otherwise.
|
|
||||||
*/
|
|
||||||
esp_err_t relay_chn_tilt_dispatch_cmd(relay_chn_tilt_ctl_t *tilt_ctl, relay_chn_tilt_cmd_t cmd);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Reset tilt counters for a relay channel.
|
|
||||||
*
|
|
||||||
* Resets both forward and reverse tilt counters to zero.
|
|
||||||
*
|
|
||||||
* @param[in] tilt_ctl Pointer to tilt control structure.
|
|
||||||
*/
|
|
||||||
void relay_chn_tilt_reset_count(relay_chn_tilt_ctl_t *tilt_ctl);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
1470
src/relay_chn.c
Normal file
1470
src/relay_chn.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,574 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2025 Kozmotronik Tech
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "esp_check.h"
|
|
||||||
#include "esp_task.h"
|
|
||||||
#include "relay_chn_output.h"
|
|
||||||
#include "relay_chn_run_info.h"
|
|
||||||
#include "relay_chn_ctl.h"
|
|
||||||
#if RELAY_CHN_ENABLE_TILTING == 1
|
|
||||||
#include "relay_chn_tilt.h"
|
|
||||||
#endif
|
|
||||||
#include "relay_chn_core.h"
|
|
||||||
|
|
||||||
|
|
||||||
static const char *TAG = "RELAY_CHN_CORE";
|
|
||||||
|
|
||||||
ESP_EVENT_DEFINE_BASE(RELAY_CHN_CMD_EVENT);
|
|
||||||
|
|
||||||
|
|
||||||
// Structure to hold a listener entry in the linked list.
|
|
||||||
typedef struct relay_chn_listener_entry_type {
|
|
||||||
relay_chn_state_listener_t listener; /*!< The listener function pointer */
|
|
||||||
ListItem_t list_item; /*!< FreeRTOS list item */
|
|
||||||
} relay_chn_listener_entry_t;
|
|
||||||
|
|
||||||
// The list that holds references to the registered listeners.
|
|
||||||
static List_t relay_chn_listener_list;
|
|
||||||
|
|
||||||
// Define the event loop for global access both for this module and tilt module.
|
|
||||||
esp_event_loop_handle_t relay_chn_event_loop = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
// Private function declarations
|
|
||||||
// Event handler for the relay channel command event
|
|
||||||
static void relay_chn_event_handler(void* handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data);
|
|
||||||
|
|
||||||
|
|
||||||
// Timer callback function for relay channel direction change inertia.
|
|
||||||
static void relay_chn_timer_cb(void* arg)
|
|
||||||
{
|
|
||||||
relay_chn_ctl_t* chn_ctl = (relay_chn_ctl_t*) arg;
|
|
||||||
// Does channel have a pending command?
|
|
||||||
if (chn_ctl->pending_cmd != RELAY_CHN_CMD_NONE) {
|
|
||||||
relay_chn_dispatch_cmd(chn_ctl, chn_ctl->pending_cmd);
|
|
||||||
chn_ctl->pending_cmd = RELAY_CHN_CMD_NONE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ESP_LOGE(TAG, "relay_chn_timer_cb: No pending cmd for relay channel %d!", chn_ctl->id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t relay_chn_init_timer(relay_chn_ctl_t *chn_ctl)
|
|
||||||
{
|
|
||||||
char timer_name[32];
|
|
||||||
snprintf(timer_name, sizeof(timer_name), "relay_chn_%d_timer", chn_ctl->id);
|
|
||||||
esp_timer_create_args_t timer_args = {
|
|
||||||
.callback = relay_chn_timer_cb,
|
|
||||||
.arg = chn_ctl,
|
|
||||||
.name = timer_name
|
|
||||||
};
|
|
||||||
return esp_timer_create(&timer_args, &chn_ctl->inertia_timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
static esp_err_t relay_chn_create_event_loop()
|
|
||||||
{
|
|
||||||
esp_event_loop_args_t loop_args = {
|
|
||||||
.queue_size = RELAY_CHN_COUNT * 8,
|
|
||||||
.task_name = "relay_chn_event_loop",
|
|
||||||
.task_priority = ESP_TASKD_EVENT_PRIO - 1,
|
|
||||||
.task_stack_size = 2048,
|
|
||||||
.task_core_id = tskNO_AFFINITY
|
|
||||||
};
|
|
||||||
esp_err_t ret = esp_event_loop_create(&loop_args, &relay_chn_event_loop);
|
|
||||||
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to create event loop for relay channel");
|
|
||||||
ret = esp_event_handler_register_with(relay_chn_event_loop,
|
|
||||||
RELAY_CHN_CMD_EVENT,
|
|
||||||
ESP_EVENT_ANY_ID,
|
|
||||||
relay_chn_event_handler, NULL);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
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_err_t ret;
|
|
||||||
// Initialize the output
|
|
||||||
ret = relay_chn_output_init(gpio_map, gpio_count);
|
|
||||||
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to initialize relay channel outputs");
|
|
||||||
|
|
||||||
// Initialize the run info
|
|
||||||
relay_chn_run_info_init();
|
|
||||||
|
|
||||||
#if RELAY_CHN_COUNT > 1
|
|
||||||
relay_chn_output_t *outputs = relay_chn_output_get_all();
|
|
||||||
relay_chn_run_info_t *run_infos = relay_chn_run_info_get_all();
|
|
||||||
#else
|
|
||||||
relay_chn_output_t *outputs = relay_chn_output_get();
|
|
||||||
relay_chn_run_info_t *run_infos = relay_chn_run_info_get();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Initialize the relay channel controls
|
|
||||||
ret = relay_chn_ctl_init(outputs, run_infos);
|
|
||||||
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to initialize relay channel control");
|
|
||||||
|
|
||||||
// Create relay channel command event loop
|
|
||||||
ret = relay_chn_create_event_loop();
|
|
||||||
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to create relay channel event loop");
|
|
||||||
|
|
||||||
#if RELAY_CHN_ENABLE_TILTING == 1
|
|
||||||
// Initialize the tilt feature
|
|
||||||
#if RELAY_CHN_COUNT > 1
|
|
||||||
relay_chn_ctl_t *chn_ctls = relay_chn_ctl_get_all();
|
|
||||||
#else
|
|
||||||
relay_chn_ctl_t *chn_ctls = relay_chn_ctl_get();
|
|
||||||
#endif // RELAY_CHN_COUNT > 1
|
|
||||||
ret = relay_chn_tilt_init(chn_ctls); // Initialize tilt feature
|
|
||||||
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to initialize tilt feature");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Init the state listener list
|
|
||||||
vListInitialise(&relay_chn_listener_list);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void relay_chn_destroy(void)
|
|
||||||
{
|
|
||||||
#if RELAY_CHN_ENABLE_TILTING == 1
|
|
||||||
relay_chn_tilt_deinit();
|
|
||||||
#endif
|
|
||||||
relay_chn_ctl_deinit();
|
|
||||||
relay_chn_output_deinit();
|
|
||||||
|
|
||||||
// Destroy the event loop
|
|
||||||
esp_event_loop_delete(relay_chn_event_loop);
|
|
||||||
relay_chn_event_loop = NULL;
|
|
||||||
|
|
||||||
// Free the listeners
|
|
||||||
while (listCURRENT_LIST_LENGTH(&relay_chn_listener_list) > 0) {
|
|
||||||
ListItem_t *pxItem = listGET_HEAD_ENTRY(&relay_chn_listener_list);
|
|
||||||
relay_chn_listener_entry_t *entry = listGET_LIST_ITEM_OWNER(pxItem);
|
|
||||||
uxListRemove(pxItem);
|
|
||||||
free(entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Find a listener entry in the list by its function pointer.
|
|
||||||
*
|
|
||||||
* This function replaces the old index-based search and is used to check
|
|
||||||
* for the existence of a listener before registration or for finding it
|
|
||||||
* during unregistration.
|
|
||||||
*
|
|
||||||
* @param listener The listener function pointer to find.
|
|
||||||
* @return Pointer to the listener entry if found, otherwise NULL.
|
|
||||||
*/
|
|
||||||
static relay_chn_listener_entry_t* find_listener_entry(relay_chn_state_listener_t listener)
|
|
||||||
{
|
|
||||||
// Iterate through the linked list of listeners
|
|
||||||
for (ListItem_t *pxListItem = listGET_HEAD_ENTRY(&relay_chn_listener_list);
|
|
||||||
pxListItem != listGET_END_MARKER(&relay_chn_listener_list);
|
|
||||||
pxListItem = listGET_NEXT(pxListItem)) {
|
|
||||||
|
|
||||||
relay_chn_listener_entry_t *entry = (relay_chn_listener_entry_t *) listGET_LIST_ITEM_OWNER(pxListItem);
|
|
||||||
if (entry->listener == listener) {
|
|
||||||
// Found the listener, return the entry
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listener was not found in the list
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t relay_chn_register_listener(relay_chn_state_listener_t listener)
|
|
||||||
{
|
|
||||||
ESP_RETURN_ON_FALSE(listener, ESP_ERR_INVALID_ARG, TAG, "Listener cannot be NULL");
|
|
||||||
|
|
||||||
// Check for duplicates
|
|
||||||
if (find_listener_entry(listener) != NULL) {
|
|
||||||
ESP_LOGD(TAG, "Listener %p already registered", listener);
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allocate memory for the new listener entry
|
|
||||||
relay_chn_listener_entry_t *entry = malloc(sizeof(relay_chn_listener_entry_t));
|
|
||||||
ESP_RETURN_ON_FALSE(entry, ESP_ERR_NO_MEM, TAG, "Failed to allocate memory for listener");
|
|
||||||
|
|
||||||
// Initialize and insert the new listener
|
|
||||||
entry->listener = listener;
|
|
||||||
vListInitialiseItem(&(entry->list_item));
|
|
||||||
listSET_LIST_ITEM_OWNER(&(entry->list_item), (void *)entry);
|
|
||||||
vListInsertEnd(&relay_chn_listener_list, &(entry->list_item));
|
|
||||||
|
|
||||||
ESP_LOGD(TAG, "Registered listener %p", listener);
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void relay_chn_unregister_listener(relay_chn_state_listener_t listener)
|
|
||||||
{
|
|
||||||
if (listener == NULL)
|
|
||||||
{
|
|
||||||
ESP_LOGD(TAG, "Cannot unregister a NULL listener.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the listener entry in the list
|
|
||||||
relay_chn_listener_entry_t *entry = find_listener_entry(listener);
|
|
||||||
|
|
||||||
if (entry != NULL) {
|
|
||||||
// Remove the item from the list and free the allocated memory
|
|
||||||
uxListRemove(&(entry->list_item));
|
|
||||||
free(entry);
|
|
||||||
ESP_LOGD(TAG, "Unregistered listener %p", listener);
|
|
||||||
} else {
|
|
||||||
ESP_LOGD(TAG, "Listener %p not found for unregistration.", listener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Dispatch relay channel command to its event loop
|
|
||||||
void relay_chn_dispatch_cmd(relay_chn_ctl_t *chn_ctl, relay_chn_cmd_t cmd) {
|
|
||||||
if (cmd == RELAY_CHN_CMD_NONE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Since the event_loop library creates a deep copy of the event data,
|
|
||||||
// and we need to pass the pointer of the relevant channel, here we need
|
|
||||||
// to pass the pointer to the pointer of the channel (&chn_ctl) so that
|
|
||||||
// the pointer value is preserved in the event data.
|
|
||||||
esp_event_post_to(relay_chn_event_loop,
|
|
||||||
RELAY_CHN_CMD_EVENT,
|
|
||||||
cmd,
|
|
||||||
&chn_ctl,
|
|
||||||
sizeof(chn_ctl),
|
|
||||||
portMAX_DELAY);
|
|
||||||
|
|
||||||
#if RELAY_CHN_ENABLE_TILTING == 1
|
|
||||||
// Reset the tilt counter when the command is either FORWARD or REVERSE
|
|
||||||
if (cmd == RELAY_CHN_CMD_FORWARD || cmd == RELAY_CHN_CMD_REVERSE) {
|
|
||||||
relay_chn_tilt_reset_count(chn_ctl->tilt_ctl);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t relay_chn_start_esp_timer_once(esp_timer_handle_t esp_timer, uint32_t time_ms)
|
|
||||||
{
|
|
||||||
esp_err_t ret = esp_timer_start_once(esp_timer, time_ms * 1000);
|
|
||||||
if (ret == ESP_ERR_INVALID_STATE) {
|
|
||||||
// This timer is already running, stop the timer first
|
|
||||||
ret = esp_timer_stop(esp_timer);
|
|
||||||
if (ret != ESP_OK && ret != ESP_ERR_INVALID_STATE) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
ret = esp_timer_start_once(esp_timer, time_ms * 1000);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void relay_chn_update_state(relay_chn_ctl_t *chn_ctl, relay_chn_state_t new_state)
|
|
||||||
{
|
|
||||||
relay_chn_state_t old_state = chn_ctl->state;
|
|
||||||
|
|
||||||
// Only update and notify if the state has actually changed.
|
|
||||||
if (old_state == new_state) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
chn_ctl->state = new_state;
|
|
||||||
|
|
||||||
// Iterate through the linked list of listeners and notify them.
|
|
||||||
for (ListItem_t *pxListItem = listGET_HEAD_ENTRY(&relay_chn_listener_list);
|
|
||||||
pxListItem != listGET_END_MARKER(&relay_chn_listener_list);
|
|
||||||
pxListItem = listGET_NEXT(pxListItem)) {
|
|
||||||
relay_chn_listener_entry_t *entry = (relay_chn_listener_entry_t *) listGET_LIST_ITEM_OWNER(pxListItem);
|
|
||||||
if (entry && entry->listener) {
|
|
||||||
// Emit the state change to the listeners
|
|
||||||
entry->listener(chn_ctl->id, old_state, new_state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief The command issuer function.
|
|
||||||
*
|
|
||||||
* This function is the deciding logic for issuing a command to a relay channel. It evaluates
|
|
||||||
* the current state of the channel before issuing the command. Then it decides whether to run
|
|
||||||
* the command immediately or wait for the opposite inertia time.
|
|
||||||
*
|
|
||||||
* The STOP command is an exception, it is always run immediately since it is safe in any case.
|
|
||||||
*
|
|
||||||
* Another special consideration is the FLIP command. If the channel is running, the FLIP command
|
|
||||||
* is issued after the channel is stopped. If the channel is stopped, the FLIP command is issued
|
|
||||||
* immediately.
|
|
||||||
*
|
|
||||||
* @param chn_ctl The relay channel to issue the command to.
|
|
||||||
* @param cmd The command to issue.
|
|
||||||
*/
|
|
||||||
void relay_chn_issue_cmd(relay_chn_ctl_t* chn_ctl, relay_chn_cmd_t cmd)
|
|
||||||
{
|
|
||||||
if (cmd == RELAY_CHN_CMD_NONE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd == RELAY_CHN_CMD_STOP) {
|
|
||||||
if (chn_ctl->state == RELAY_CHN_STATE_STOPPED) {
|
|
||||||
return; // Do nothing if already stopped
|
|
||||||
}
|
|
||||||
// If the command is STOP, issue it immediately
|
|
||||||
relay_chn_dispatch_cmd(chn_ctl, cmd);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
relay_chn_cmd_t last_run_cmd = relay_chn_run_info_get_last_run_cmd(chn_ctl->run_info);
|
|
||||||
// Evaluate the channel's next move depending on its status
|
|
||||||
switch (chn_ctl->state)
|
|
||||||
{
|
|
||||||
case RELAY_CHN_STATE_IDLE:
|
|
||||||
// If the channel is idle, run the command immediately
|
|
||||||
relay_chn_dispatch_cmd(chn_ctl, cmd);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RELAY_CHN_STATE_FORWARD_PENDING:
|
|
||||||
case RELAY_CHN_STATE_REVERSE_PENDING:
|
|
||||||
// The channel is already waiting for the opposite inertia time,
|
|
||||||
// so do nothing unless the command is STOP
|
|
||||||
if (cmd == RELAY_CHN_CMD_STOP) {
|
|
||||||
relay_chn_dispatch_cmd(chn_ctl, cmd);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RELAY_CHN_STATE_STOPPED:
|
|
||||||
if (last_run_cmd == cmd || last_run_cmd == RELAY_CHN_CMD_NONE) {
|
|
||||||
// Since the state is STOPPED, the inertia timer should be running and must be invalidated
|
|
||||||
// with the pending FREE command
|
|
||||||
esp_timer_stop(chn_ctl->inertia_timer);
|
|
||||||
chn_ctl->pending_cmd = RELAY_CHN_CMD_NONE;
|
|
||||||
|
|
||||||
// If this is the first run or the last run command is the same as the current command,
|
|
||||||
// run the command immediately
|
|
||||||
relay_chn_dispatch_cmd(chn_ctl, cmd);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// If the last run command is different from the current command, calculate the time passed
|
|
||||||
// since the last run command stopped and decide whether to run the command immediately or wait
|
|
||||||
uint32_t last_run_cmd_time_ms = relay_chn_run_info_get_last_run_cmd_time_ms(chn_ctl->run_info);
|
|
||||||
uint32_t inertia_time_passed_ms = (uint32_t) (esp_timer_get_time() / 1000) - last_run_cmd_time_ms;
|
|
||||||
uint32_t inertia_time_ms = RELAY_CHN_OPPOSITE_INERTIA_MS - inertia_time_passed_ms;
|
|
||||||
if (inertia_time_ms > 0) {
|
|
||||||
chn_ctl->pending_cmd = cmd;
|
|
||||||
relay_chn_state_t new_state = cmd == RELAY_CHN_CMD_FORWARD
|
|
||||||
? RELAY_CHN_STATE_FORWARD_PENDING : RELAY_CHN_STATE_REVERSE_PENDING;
|
|
||||||
relay_chn_update_state(chn_ctl, new_state);
|
|
||||||
// If the time passed is less than the opposite inertia time, wait for the remaining time
|
|
||||||
relay_chn_start_esp_timer_once(chn_ctl->inertia_timer, inertia_time_ms);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// If the time passed is more than the opposite inertia time, run the command immediately
|
|
||||||
relay_chn_dispatch_cmd(chn_ctl, cmd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RELAY_CHN_STATE_FORWARD:
|
|
||||||
case RELAY_CHN_STATE_REVERSE:
|
|
||||||
if (cmd == RELAY_CHN_CMD_FLIP) {
|
|
||||||
// If the command is FLIP, stop the running channel first, then issue the FLIP command
|
|
||||||
relay_chn_dispatch_cmd(chn_ctl, RELAY_CHN_CMD_STOP);
|
|
||||||
relay_chn_dispatch_cmd(chn_ctl, cmd);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (last_run_cmd == cmd) {
|
|
||||||
// If the last run command is the same as the current command, do nothing
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop the channel first before the schedule
|
|
||||||
relay_chn_dispatch_cmd(chn_ctl, RELAY_CHN_CMD_STOP);
|
|
||||||
|
|
||||||
// If the last run command is different from the current command, wait for the opposite inertia time
|
|
||||||
chn_ctl->pending_cmd = cmd;
|
|
||||||
relay_chn_state_t new_state = cmd == RELAY_CHN_CMD_FORWARD
|
|
||||||
? RELAY_CHN_STATE_FORWARD_PENDING : RELAY_CHN_STATE_REVERSE_PENDING;
|
|
||||||
relay_chn_update_state(chn_ctl, new_state);
|
|
||||||
relay_chn_start_esp_timer_once(chn_ctl->inertia_timer, RELAY_CHN_OPPOSITE_INERTIA_MS);
|
|
||||||
break;
|
|
||||||
|
|
||||||
#if RELAY_CHN_ENABLE_TILTING == 1
|
|
||||||
case RELAY_CHN_STATE_TILT_FORWARD:
|
|
||||||
// Terminate tilting first
|
|
||||||
relay_chn_tilt_dispatch_cmd(chn_ctl->tilt_ctl, RELAY_CHN_TILT_CMD_STOP);
|
|
||||||
if (cmd == RELAY_CHN_CMD_FORWARD) {
|
|
||||||
// Schedule for running forward
|
|
||||||
chn_ctl->pending_cmd = cmd;
|
|
||||||
relay_chn_update_state(chn_ctl, RELAY_CHN_STATE_FORWARD_PENDING);
|
|
||||||
relay_chn_start_esp_timer_once(chn_ctl->inertia_timer, RELAY_CHN_OPPOSITE_INERTIA_MS);
|
|
||||||
} else if (cmd == RELAY_CHN_CMD_REVERSE) {
|
|
||||||
// Run directly since it is the same direction
|
|
||||||
relay_chn_dispatch_cmd(chn_ctl, cmd);
|
|
||||||
relay_chn_update_state(chn_ctl, RELAY_CHN_STATE_REVERSE);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RELAY_CHN_STATE_TILT_REVERSE:
|
|
||||||
// Terminate tilting first
|
|
||||||
relay_chn_tilt_dispatch_cmd(chn_ctl->tilt_ctl, RELAY_CHN_TILT_CMD_STOP);
|
|
||||||
if (cmd == RELAY_CHN_CMD_FORWARD) {
|
|
||||||
// Run directly since it is the same direction
|
|
||||||
relay_chn_dispatch_cmd(chn_ctl, cmd);
|
|
||||||
relay_chn_update_state(chn_ctl, RELAY_CHN_STATE_FORWARD);
|
|
||||||
} else if (cmd == RELAY_CHN_CMD_REVERSE) {
|
|
||||||
// Schedule for running reverse
|
|
||||||
chn_ctl->pending_cmd = cmd;
|
|
||||||
relay_chn_update_state(chn_ctl, RELAY_CHN_STATE_REVERSE_PENDING);
|
|
||||||
relay_chn_start_esp_timer_once(chn_ctl->inertia_timer, RELAY_CHN_OPPOSITE_INERTIA_MS);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
default: ESP_LOGD(TAG, "relay_chn_evaluate: Unknown relay channel state!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if RELAY_CHN_COUNT > 1
|
|
||||||
bool relay_chn_is_channel_id_valid(uint8_t chn_id)
|
|
||||||
{
|
|
||||||
bool valid = (chn_id < RELAY_CHN_COUNT) || chn_id == RELAY_CHN_ID_ALL;
|
|
||||||
if (!valid) {
|
|
||||||
ESP_LOGE(TAG, "Invalid channel ID: %d", chn_id);
|
|
||||||
}
|
|
||||||
return valid;
|
|
||||||
}
|
|
||||||
#endif // RELAY_CHN_COUNT > 1
|
|
||||||
|
|
||||||
|
|
||||||
static void relay_chn_execute_stop(relay_chn_ctl_t *chn_ctl)
|
|
||||||
{
|
|
||||||
if (relay_chn_output_stop(chn_ctl->output) != ESP_OK) {
|
|
||||||
ESP_LOGE(TAG, "relay_chn_execute_stop: Failed to output stop for relay channel #%d!", chn_ctl->id);
|
|
||||||
}
|
|
||||||
relay_chn_state_t previous_state = chn_ctl->state;
|
|
||||||
relay_chn_update_state(chn_ctl, RELAY_CHN_STATE_STOPPED);
|
|
||||||
|
|
||||||
// If there is any pending command, cancel it since the STOP command is issued right after it
|
|
||||||
chn_ctl->pending_cmd = RELAY_CHN_CMD_NONE;
|
|
||||||
// Invalidate the channel's timer if it is active
|
|
||||||
esp_timer_stop(chn_ctl->inertia_timer);
|
|
||||||
|
|
||||||
// Save the last run time only if the previous state was either STATE FORWARD
|
|
||||||
// or STATE_REVERSE. Then schedule a free command.
|
|
||||||
if (previous_state == RELAY_CHN_STATE_FORWARD || previous_state == RELAY_CHN_STATE_REVERSE) {
|
|
||||||
// Record the command's last run time
|
|
||||||
relay_chn_run_info_set_last_run_cmd_time_ms(chn_ctl->run_info, (uint32_t)(esp_timer_get_time() / 1000));
|
|
||||||
// Schedule a free command for the channel
|
|
||||||
chn_ctl->pending_cmd = RELAY_CHN_CMD_IDLE;
|
|
||||||
relay_chn_start_esp_timer_once(chn_ctl->inertia_timer, RELAY_CHN_OPPOSITE_INERTIA_MS);
|
|
||||||
} else {
|
|
||||||
// If the channel was not running one of the run or fwd, issue a free command immediately
|
|
||||||
relay_chn_dispatch_cmd(chn_ctl, RELAY_CHN_CMD_IDLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void relay_chn_execute_forward(relay_chn_ctl_t *chn_ctl)
|
|
||||||
{
|
|
||||||
if (relay_chn_output_forward(chn_ctl->output) != ESP_OK) {
|
|
||||||
ESP_LOGE(TAG, "relay_chn_execute_forward: Failed to output forward for relay channel #%d!", chn_ctl->id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
relay_chn_run_info_set_last_run_cmd(chn_ctl->run_info, RELAY_CHN_CMD_FORWARD);
|
|
||||||
relay_chn_update_state(chn_ctl, RELAY_CHN_STATE_FORWARD);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void relay_chn_execute_reverse(relay_chn_ctl_t *chn_ctl)
|
|
||||||
{
|
|
||||||
if (relay_chn_output_reverse(chn_ctl->output) != ESP_OK) {
|
|
||||||
ESP_LOGE(TAG, "relay_chn_execute_reverse: Failed to output reverse for relay channel #%d!", chn_ctl->id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
relay_chn_run_info_set_last_run_cmd(chn_ctl->run_info, RELAY_CHN_CMD_REVERSE);
|
|
||||||
relay_chn_update_state(chn_ctl, RELAY_CHN_STATE_REVERSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void relay_chn_execute_flip(relay_chn_ctl_t *chn_ctl)
|
|
||||||
{
|
|
||||||
relay_chn_output_flip(chn_ctl->output);
|
|
||||||
// Set an inertia on the channel to prevent any immediate movement
|
|
||||||
chn_ctl->pending_cmd = RELAY_CHN_CMD_IDLE;
|
|
||||||
relay_chn_start_esp_timer_once(chn_ctl->inertia_timer, RELAY_CHN_OPPOSITE_INERTIA_MS);
|
|
||||||
}
|
|
||||||
|
|
||||||
void relay_chn_execute_idle(relay_chn_ctl_t *chn_ctl)
|
|
||||||
{
|
|
||||||
chn_ctl->pending_cmd = RELAY_CHN_CMD_NONE;
|
|
||||||
// Invalidate the channel's timer if it is active
|
|
||||||
esp_timer_stop(chn_ctl->inertia_timer);
|
|
||||||
relay_chn_update_state(chn_ctl, RELAY_CHN_STATE_IDLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void relay_chn_event_handler(void* handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
|
|
||||||
{
|
|
||||||
relay_chn_ctl_t* chn_ctl = *(relay_chn_ctl_t**) event_data;
|
|
||||||
ESP_RETURN_VOID_ON_FALSE(chn_ctl != NULL, TAG, "event_data is NULL");
|
|
||||||
ESP_LOGD(TAG, "relay_chn_event_handler: Command: %s", relay_chn_cmd_str(event_id));
|
|
||||||
|
|
||||||
switch (event_id) {
|
|
||||||
case RELAY_CHN_CMD_STOP:
|
|
||||||
relay_chn_execute_stop(chn_ctl);
|
|
||||||
break;
|
|
||||||
case RELAY_CHN_CMD_FORWARD:
|
|
||||||
relay_chn_execute_forward(chn_ctl);
|
|
||||||
break;
|
|
||||||
case RELAY_CHN_CMD_REVERSE:
|
|
||||||
relay_chn_execute_reverse(chn_ctl);
|
|
||||||
break;
|
|
||||||
case RELAY_CHN_CMD_FLIP:
|
|
||||||
relay_chn_execute_flip(chn_ctl);
|
|
||||||
break;
|
|
||||||
case RELAY_CHN_CMD_IDLE:
|
|
||||||
relay_chn_execute_idle(chn_ctl);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ESP_LOGD(TAG, "Unknown relay channel command!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char *relay_chn_cmd_str(relay_chn_cmd_t cmd)
|
|
||||||
{
|
|
||||||
switch (cmd) {
|
|
||||||
case RELAY_CHN_CMD_STOP:
|
|
||||||
return "STOP";
|
|
||||||
case RELAY_CHN_CMD_FORWARD:
|
|
||||||
return "FORWARD";
|
|
||||||
case RELAY_CHN_CMD_REVERSE:
|
|
||||||
return "REVERSE";
|
|
||||||
case RELAY_CHN_CMD_FLIP:
|
|
||||||
return "FLIP";
|
|
||||||
case RELAY_CHN_CMD_IDLE:
|
|
||||||
return "IDLE";
|
|
||||||
default:
|
|
||||||
return "UNKNOWN";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char *relay_chn_state_str(relay_chn_state_t state)
|
|
||||||
{
|
|
||||||
switch (state) {
|
|
||||||
case RELAY_CHN_STATE_IDLE:
|
|
||||||
return "IDLE";
|
|
||||||
case RELAY_CHN_STATE_STOPPED:
|
|
||||||
return "STOPPED";
|
|
||||||
case RELAY_CHN_STATE_FORWARD:
|
|
||||||
return "FORWARD";
|
|
||||||
case RELAY_CHN_STATE_REVERSE:
|
|
||||||
return "REVERSE";
|
|
||||||
case RELAY_CHN_STATE_FORWARD_PENDING:
|
|
||||||
return "FORWARD_PENDING";
|
|
||||||
case RELAY_CHN_STATE_REVERSE_PENDING:
|
|
||||||
return "REVERSE_PENDING";
|
|
||||||
#if RELAY_CHN_ENABLE_TILTING == 1
|
|
||||||
case RELAY_CHN_STATE_TILT_FORWARD:
|
|
||||||
return "TILT_FORWARD";
|
|
||||||
case RELAY_CHN_STATE_TILT_REVERSE:
|
|
||||||
return "TILT_REVERSE";
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
return "UNKNOWN";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,137 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2025 Kozmotronik Tech
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "esp_check.h"
|
|
||||||
#include "relay_chn_priv_types.h"
|
|
||||||
#include "relay_chn_core.h"
|
|
||||||
#include "relay_chn_ctl.h"
|
|
||||||
#include "relay_chn_output.h"
|
|
||||||
|
|
||||||
static const char *TAG = "RELAY_CHN_CTL";
|
|
||||||
|
|
||||||
static relay_chn_ctl_t chn_ctls[RELAY_CHN_COUNT];
|
|
||||||
|
|
||||||
|
|
||||||
esp_err_t relay_chn_ctl_init(relay_chn_output_t *outputs, relay_chn_run_info_t *run_infos)
|
|
||||||
{
|
|
||||||
// Initialize all relay channels
|
|
||||||
esp_err_t ret;
|
|
||||||
for (int i = 0; i < RELAY_CHN_COUNT; i++) {
|
|
||||||
relay_chn_ctl_t* chn_ctl = &chn_ctls[i];
|
|
||||||
relay_chn_output_t* output = &outputs[i];
|
|
||||||
relay_chn_run_info_t* run_info = &run_infos[i];
|
|
||||||
|
|
||||||
chn_ctl->id = i;
|
|
||||||
chn_ctl->state = RELAY_CHN_STATE_IDLE;
|
|
||||||
chn_ctl->pending_cmd = RELAY_CHN_CMD_NONE;
|
|
||||||
|
|
||||||
chn_ctl->output = output;
|
|
||||||
chn_ctl->run_info = run_info;
|
|
||||||
ret = relay_chn_init_timer(chn_ctl); // Create direction change inertia timer
|
|
||||||
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to create relay channel timer for channel %d", i);
|
|
||||||
}
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void relay_chn_ctl_deinit()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < RELAY_CHN_COUNT; i++) {
|
|
||||||
relay_chn_ctl_t* chn_ctl = &chn_ctls[i];
|
|
||||||
if (chn_ctl->inertia_timer != NULL) {
|
|
||||||
esp_timer_delete(chn_ctl->inertia_timer);
|
|
||||||
chn_ctl->inertia_timer = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
relay_chn_state_t relay_chn_ctl_get_state(uint8_t chn_id)
|
|
||||||
{
|
|
||||||
if (!relay_chn_is_channel_id_valid(chn_id) || chn_id == RELAY_CHN_ID_ALL) {
|
|
||||||
return RELAY_CHN_STATE_UNDEFINED;
|
|
||||||
}
|
|
||||||
return chn_ctls[chn_id].state;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *relay_chn_ctl_get_state_str(uint8_t chn_id)
|
|
||||||
{
|
|
||||||
if (!relay_chn_is_channel_id_valid(chn_id) || chn_id == RELAY_CHN_ID_ALL) {
|
|
||||||
return relay_chn_state_str(RELAY_CHN_STATE_UNDEFINED);
|
|
||||||
}
|
|
||||||
return relay_chn_state_str(chn_ctls[chn_id].state);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void relay_chn_ctl_issue_cmd_on_all_channels(relay_chn_cmd_t cmd)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < RELAY_CHN_COUNT; i++) {
|
|
||||||
relay_chn_issue_cmd(&chn_ctls[i], cmd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void relay_chn_ctl_run_forward(uint8_t chn_id)
|
|
||||||
{
|
|
||||||
if (!relay_chn_is_channel_id_valid(chn_id)) return;
|
|
||||||
|
|
||||||
if (chn_id == RELAY_CHN_ID_ALL) {
|
|
||||||
relay_chn_ctl_issue_cmd_on_all_channels(RELAY_CHN_CMD_FORWARD);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
relay_chn_issue_cmd(&chn_ctls[chn_id], RELAY_CHN_CMD_FORWARD);
|
|
||||||
}
|
|
||||||
|
|
||||||
void relay_chn_ctl_run_reverse(uint8_t chn_id)
|
|
||||||
{
|
|
||||||
if (!relay_chn_is_channel_id_valid(chn_id)) return;
|
|
||||||
|
|
||||||
if (chn_id == RELAY_CHN_ID_ALL) {
|
|
||||||
relay_chn_ctl_issue_cmd_on_all_channels(RELAY_CHN_CMD_REVERSE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
relay_chn_issue_cmd(&chn_ctls[chn_id], RELAY_CHN_CMD_REVERSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void relay_chn_ctl_stop(uint8_t chn_id)
|
|
||||||
{
|
|
||||||
if (!relay_chn_is_channel_id_valid(chn_id)) return;
|
|
||||||
|
|
||||||
if (chn_id == RELAY_CHN_ID_ALL) {
|
|
||||||
relay_chn_ctl_issue_cmd_on_all_channels(RELAY_CHN_CMD_STOP);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
relay_chn_issue_cmd(&chn_ctls[chn_id], RELAY_CHN_CMD_STOP);
|
|
||||||
}
|
|
||||||
|
|
||||||
void relay_chn_ctl_flip_direction(uint8_t chn_id)
|
|
||||||
{
|
|
||||||
if (!relay_chn_is_channel_id_valid(chn_id)) return;
|
|
||||||
|
|
||||||
if (chn_id == RELAY_CHN_ID_ALL) {
|
|
||||||
relay_chn_ctl_issue_cmd_on_all_channels(RELAY_CHN_CMD_FLIP);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
relay_chn_issue_cmd(&chn_ctls[chn_id], RELAY_CHN_CMD_FLIP);
|
|
||||||
}
|
|
||||||
|
|
||||||
relay_chn_direction_t relay_chn_ctl_get_direction(uint8_t chn_id)
|
|
||||||
{
|
|
||||||
if (!relay_chn_is_channel_id_valid(chn_id)) {
|
|
||||||
return RELAY_CHN_DIRECTION_DEFAULT;
|
|
||||||
}
|
|
||||||
relay_chn_ctl_t *chn_ctl = &chn_ctls[chn_id];
|
|
||||||
return relay_chn_output_get_direction(chn_ctl->output);
|
|
||||||
}
|
|
||||||
|
|
||||||
relay_chn_ctl_t *relay_chn_ctl_get(uint8_t chn_id)
|
|
||||||
{
|
|
||||||
if (!relay_chn_is_channel_id_valid(chn_id)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return &chn_ctls[chn_id];
|
|
||||||
}
|
|
||||||
|
|
||||||
relay_chn_ctl_t *relay_chn_ctl_get_all(void)
|
|
||||||
{
|
|
||||||
return chn_ctls;
|
|
||||||
}
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2025 Kozmotronik Tech
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "relay_chn_priv_types.h"
|
|
||||||
#include "relay_chn_core.h"
|
|
||||||
#include "relay_chn_ctl.h"
|
|
||||||
#include "relay_chn_output.h"
|
|
||||||
|
|
||||||
|
|
||||||
static relay_chn_ctl_t chn_ctl;
|
|
||||||
|
|
||||||
|
|
||||||
esp_err_t relay_chn_ctl_init(relay_chn_output_t *output, relay_chn_run_info_t *run_info)
|
|
||||||
{
|
|
||||||
// Initialize the relay channel
|
|
||||||
chn_ctl.id = 0; // Single channel, so ID is 0
|
|
||||||
chn_ctl.state = RELAY_CHN_STATE_IDLE;
|
|
||||||
chn_ctl.pending_cmd = RELAY_CHN_CMD_NONE;
|
|
||||||
chn_ctl.output = output;
|
|
||||||
chn_ctl.run_info = run_info;
|
|
||||||
return relay_chn_init_timer(&chn_ctl); // Create direction change inertia timer
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void relay_chn_ctl_deinit()
|
|
||||||
{
|
|
||||||
if (chn_ctl.inertia_timer != NULL) {
|
|
||||||
esp_timer_delete(chn_ctl.inertia_timer);
|
|
||||||
chn_ctl.inertia_timer = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* relay_chn APIs */
|
|
||||||
relay_chn_state_t relay_chn_ctl_get_state()
|
|
||||||
{
|
|
||||||
return chn_ctl.state;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *relay_chn_ctl_get_state_str()
|
|
||||||
{
|
|
||||||
return relay_chn_state_str(chn_ctl.state);
|
|
||||||
}
|
|
||||||
|
|
||||||
void relay_chn_ctl_run_forward()
|
|
||||||
{
|
|
||||||
relay_chn_issue_cmd(&chn_ctl, RELAY_CHN_CMD_FORWARD);
|
|
||||||
}
|
|
||||||
|
|
||||||
void relay_chn_ctl_run_reverse()
|
|
||||||
{
|
|
||||||
relay_chn_issue_cmd(&chn_ctl, RELAY_CHN_CMD_REVERSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void relay_chn_ctl_stop()
|
|
||||||
{
|
|
||||||
relay_chn_issue_cmd(&chn_ctl, RELAY_CHN_CMD_STOP);
|
|
||||||
}
|
|
||||||
|
|
||||||
void relay_chn_ctl_flip_direction()
|
|
||||||
{
|
|
||||||
relay_chn_issue_cmd(&chn_ctl, RELAY_CHN_CMD_FLIP);
|
|
||||||
}
|
|
||||||
|
|
||||||
relay_chn_direction_t relay_chn_ctl_get_direction()
|
|
||||||
{
|
|
||||||
return relay_chn_output_get_direction(chn_ctl.output);
|
|
||||||
}
|
|
||||||
/* relay_chn APIs */
|
|
||||||
|
|
||||||
relay_chn_ctl_t *relay_chn_ctl_get()
|
|
||||||
{
|
|
||||||
return &chn_ctl;
|
|
||||||
}
|
|
||||||
@@ -1,168 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2025 Kozmotronik Tech
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "esp_check.h"
|
|
||||||
#include "esp_log.h"
|
|
||||||
#include "relay_chn_defs.h"
|
|
||||||
#include "relay_chn_output.h"
|
|
||||||
#include "relay_chn_core.h"
|
|
||||||
|
|
||||||
|
|
||||||
static const char *TAG = "RELAY_CHN_OUTPUT";
|
|
||||||
|
|
||||||
#if RELAY_CHN_COUNT > 1
|
|
||||||
static relay_chn_output_t outputs[RELAY_CHN_COUNT];
|
|
||||||
#else
|
|
||||||
static relay_chn_output_t output;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static esp_err_t relay_chn_output_check_gpio_capabilities(uint8_t gpio_count)
|
|
||||||
{
|
|
||||||
// Check if the device's GPIOs are enough for the number of channels
|
|
||||||
if (RELAY_CHN_COUNT > (GPIO_PIN_COUNT / 2)) {
|
|
||||||
ESP_LOGE(TAG, "Not enough GPIOs for the number of channels!");
|
|
||||||
ESP_LOGE(TAG, "Max available num of channels: %d, requested channels: %d", GPIO_PIN_COUNT / 2, RELAY_CHN_COUNT);
|
|
||||||
return ESP_ERR_INVALID_ARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the provided GPIOs correspond to the number of channels
|
|
||||||
if (gpio_count != RELAY_CHN_COUNT * 2) {
|
|
||||||
ESP_LOGE(TAG, "Invalid number of GPIOs provided: %d", gpio_count);
|
|
||||||
ESP_LOGE(TAG, "Expected number of GPIOs: %d", RELAY_CHN_COUNT * 2);
|
|
||||||
return ESP_ERR_INVALID_ARG;
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
ESP_RETURN_ON_FALSE(GPIO_IS_VALID_OUTPUT_GPIO(reverse_pin), ESP_ERR_INVALID_ARG, TAG,
|
|
||||||
"Invalid GPIO pin number for reverse_pin: %d", reverse_pin);
|
|
||||||
|
|
||||||
// Check if the GPIOs are valid
|
|
||||||
esp_err_t ret;
|
|
||||||
// Initialize the GPIOs
|
|
||||||
ret = gpio_reset_pin(forward_pin);
|
|
||||||
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to reset GPIO forward pin: %d", forward_pin);
|
|
||||||
ret = gpio_set_direction(forward_pin, GPIO_MODE_OUTPUT);
|
|
||||||
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to set GPIO direction for forward pin: %d", forward_pin);
|
|
||||||
|
|
||||||
ret = gpio_reset_pin(reverse_pin);
|
|
||||||
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to reset GPIO reverse pin: %d", reverse_pin);
|
|
||||||
ret = gpio_set_direction(reverse_pin, GPIO_MODE_OUTPUT);
|
|
||||||
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to set GPIO direction for reverse pin: %d", reverse_pin);
|
|
||||||
// Initialize the GPIOs
|
|
||||||
|
|
||||||
// Initialize the relay channel output
|
|
||||||
output->forward_pin = forward_pin;
|
|
||||||
output->reverse_pin = reverse_pin;
|
|
||||||
output->direction = RELAY_CHN_DIRECTION_DEFAULT;
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t relay_chn_output_init(const uint8_t* gpio_map, uint8_t gpio_count)
|
|
||||||
{
|
|
||||||
esp_err_t ret;
|
|
||||||
ret = relay_chn_output_check_gpio_capabilities(gpio_count);
|
|
||||||
ESP_RETURN_ON_ERROR(ret, TAG, "Device does not support the provided GPIOs");
|
|
||||||
|
|
||||||
#if RELAY_CHN_COUNT > 1
|
|
||||||
for (int i = 0; i < RELAY_CHN_COUNT; i++) {
|
|
||||||
relay_chn_output_t* output = &outputs[i];
|
|
||||||
int gpio_index = i << 1; // gpio_index = i * 2
|
|
||||||
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];
|
|
||||||
|
|
||||||
ret = relay_chn_output_ctl_init(output, forward_pin, reverse_pin);
|
|
||||||
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to initialize relay channel %d", i);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
ret = relay_chn_output_ctl_init(&output, gpio_map[0], gpio_map[1]);
|
|
||||||
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to initialize relay channel");
|
|
||||||
#endif
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void relay_chn_output_ctl_deinit(relay_chn_output_t *output)
|
|
||||||
{
|
|
||||||
gpio_reset_pin(output->forward_pin);
|
|
||||||
gpio_reset_pin(output->reverse_pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
void relay_chn_output_deinit()
|
|
||||||
{
|
|
||||||
#if RELAY_CHN_COUNT > 1
|
|
||||||
for (int i = 0; i < RELAY_CHN_COUNT; i++) {
|
|
||||||
relay_chn_output_ctl_deinit(&outputs[i]);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
relay_chn_output_ctl_deinit(&output);
|
|
||||||
#endif // RELAY_CHN_COUNT > 1
|
|
||||||
}
|
|
||||||
|
|
||||||
#if RELAY_CHN_COUNT > 1
|
|
||||||
relay_chn_output_t *relay_chn_output_get(uint8_t chn_id)
|
|
||||||
{
|
|
||||||
if (!relay_chn_is_channel_id_valid(chn_id)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return &outputs[chn_id];
|
|
||||||
}
|
|
||||||
|
|
||||||
relay_chn_output_t *relay_chn_output_get_all(void)
|
|
||||||
{
|
|
||||||
return outputs;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
relay_chn_output_t *relay_chn_output_get(void)
|
|
||||||
{
|
|
||||||
return &output;
|
|
||||||
}
|
|
||||||
#endif // RELAY_CHN_COUNT > 1
|
|
||||||
|
|
||||||
esp_err_t relay_chn_output_stop(relay_chn_output_t *output)
|
|
||||||
{
|
|
||||||
esp_err_t ret;
|
|
||||||
ret = gpio_set_level(output->forward_pin, 0);
|
|
||||||
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to set forward pin to LOW");
|
|
||||||
return gpio_set_level(output->reverse_pin, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t relay_chn_output_forward(relay_chn_output_t *output)
|
|
||||||
{
|
|
||||||
esp_err_t ret;
|
|
||||||
ret = gpio_set_level(output->forward_pin, 1);
|
|
||||||
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to set forward pin to HIGH");
|
|
||||||
return gpio_set_level(output->reverse_pin, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t relay_chn_output_reverse(relay_chn_output_t *output)
|
|
||||||
{
|
|
||||||
esp_err_t ret;
|
|
||||||
ret = gpio_set_level(output->forward_pin, 0);
|
|
||||||
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to set forward pin to LOW");
|
|
||||||
return gpio_set_level(output->reverse_pin, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void relay_chn_output_flip(relay_chn_output_t *output)
|
|
||||||
{
|
|
||||||
// Flip the output GPIO pins
|
|
||||||
gpio_num_t temp = output->forward_pin;
|
|
||||||
output->forward_pin = output->reverse_pin;
|
|
||||||
output->reverse_pin = temp;
|
|
||||||
// Flip the direction
|
|
||||||
output->direction = (output->direction == RELAY_CHN_DIRECTION_DEFAULT)
|
|
||||||
? RELAY_CHN_DIRECTION_FLIPPED
|
|
||||||
: RELAY_CHN_DIRECTION_DEFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
relay_chn_direction_t relay_chn_output_get_direction(relay_chn_output_t *output)
|
|
||||||
{
|
|
||||||
return output->direction;
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2025 Kozmotronik Tech
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "relay_chn_core.h"
|
|
||||||
#include "relay_chn_run_info.h"
|
|
||||||
|
|
||||||
|
|
||||||
#if RELAY_CHN_COUNT > 1
|
|
||||||
static relay_chn_run_info_t run_infos[RELAY_CHN_COUNT];
|
|
||||||
#else
|
|
||||||
static relay_chn_run_info_t run_info;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void relay_chn_run_info_init()
|
|
||||||
{
|
|
||||||
#if RELAY_CHN_COUNT > 1
|
|
||||||
for (int i = 0; i < RELAY_CHN_COUNT; i++) {
|
|
||||||
run_infos[i].last_run_cmd = RELAY_CHN_CMD_NONE;
|
|
||||||
run_infos[i].last_run_cmd_time_ms = 0;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
run_info.last_run_cmd = RELAY_CHN_CMD_NONE;
|
|
||||||
run_info.last_run_cmd_time_ms = 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if RELAY_CHN_COUNT > 1
|
|
||||||
relay_chn_run_info_t *relay_chn_run_info_get(uint8_t chn_id)
|
|
||||||
{
|
|
||||||
if (!relay_chn_is_channel_id_valid(chn_id)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return &run_infos[chn_id];
|
|
||||||
}
|
|
||||||
|
|
||||||
relay_chn_run_info_t *relay_chn_run_info_get_all()
|
|
||||||
{
|
|
||||||
return run_infos;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
relay_chn_run_info_t *relay_chn_run_info_get()
|
|
||||||
{
|
|
||||||
return &run_info;
|
|
||||||
}
|
|
||||||
#endif // RELAY_CHN_COUNT > 1
|
|
||||||
|
|
||||||
relay_chn_cmd_t relay_chn_run_info_get_last_run_cmd(relay_chn_run_info_t *run_info)
|
|
||||||
{
|
|
||||||
return run_info == NULL ? RELAY_CHN_CMD_NONE : run_info->last_run_cmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
void relay_chn_run_info_set_last_run_cmd(relay_chn_run_info_t *run_info, relay_chn_cmd_t cmd)
|
|
||||||
{
|
|
||||||
if (!run_info) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
run_info->last_run_cmd = cmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t relay_chn_run_info_get_last_run_cmd_time_ms(relay_chn_run_info_t *run_info)
|
|
||||||
{
|
|
||||||
return run_info == NULL ? 0 : run_info->last_run_cmd_time_ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
void relay_chn_run_info_set_last_run_cmd_time_ms(relay_chn_run_info_t *run_info, uint32_t time_ms)
|
|
||||||
{
|
|
||||||
if (!run_info) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
run_info->last_run_cmd_time_ms = time_ms;
|
|
||||||
}
|
|
||||||
@@ -1,634 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2025 Kozmotronik Tech
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "esp_check.h"
|
|
||||||
#include "relay_chn_core.h"
|
|
||||||
#include "relay_chn_output.h"
|
|
||||||
#include "relay_chn_run_info.h"
|
|
||||||
#include "relay_chn_tilt.h"
|
|
||||||
|
|
||||||
|
|
||||||
static const char *TAG = "RELAY_CHN_TILT";
|
|
||||||
|
|
||||||
/**@{*/
|
|
||||||
/*
|
|
||||||
* Tilt Pattern Timing Definitions
|
|
||||||
*
|
|
||||||
* The min and max timing definitions as well as the default timing definitions.
|
|
||||||
* These definitions are used to define and adjust the tilt sensitivity.
|
|
||||||
*/
|
|
||||||
#define RELAY_CHN_TILT_RUN_MIN_MS 50
|
|
||||||
#define RELAY_CHN_TILT_RUN_MAX_MS 10
|
|
||||||
#define RELAY_CHN_TILT_PAUSE_MIN_MS 450
|
|
||||||
#define RELAY_CHN_TILT_PAUSE_MAX_MS 90
|
|
||||||
|
|
||||||
#define RELAY_CHN_TILT_DEFAULT_RUN_MS 15
|
|
||||||
#define RELAY_CHN_TILT_DEFAULT_PAUSE_MS 150
|
|
||||||
|
|
||||||
#define RELAY_CHN_TILT_DEFAULT_SENSITIVITY \
|
|
||||||
( (RELAY_CHN_TILT_DEFAULT_RUN_MS - RELAY_CHN_TILT_RUN_MIN_MS) \
|
|
||||||
* 100 / (RELAY_CHN_TILT_RUN_MAX_MS - RELAY_CHN_TILT_RUN_MIN_MS) )
|
|
||||||
/**@}*/
|
|
||||||
|
|
||||||
ESP_EVENT_DEFINE_BASE(RELAY_CHN_TILT_CMD_EVENT_BASE);
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Tilt steps.
|
|
||||||
typedef enum {
|
|
||||||
RELAY_CHN_TILT_STEP_NONE, /*!< No step */
|
|
||||||
RELAY_CHN_TILT_STEP_PENDING, /*!< Pending step */
|
|
||||||
RELAY_CHN_TILT_STEP_MOVE, /*!< Move step. Tilt is driving either for forward or reverse */
|
|
||||||
RELAY_CHN_TILT_STEP_PAUSE /*!< Pause step. Tilt is paused */
|
|
||||||
} relay_chn_tilt_step_t;
|
|
||||||
|
|
||||||
/// @brief Tilt timing structure to manage tilt pattern timing.
|
|
||||||
typedef struct {
|
|
||||||
uint8_t sensitivity; /*!< Tilt sensitivity in percentage (%) */
|
|
||||||
uint32_t move_time_ms; /*!< Move time in milliseconds */
|
|
||||||
uint32_t pause_time_ms; /*!< Pause time in milliseconds */
|
|
||||||
} relay_chn_tilt_timing_t;
|
|
||||||
|
|
||||||
/// @brief Tilt counter structure to manage tilt count.
|
|
||||||
typedef struct {
|
|
||||||
uint32_t tilt_forward_count; /*!< Tilt forward count */
|
|
||||||
uint32_t tilt_reverse_count; /*!< Tilt reverse count */
|
|
||||||
} relay_chn_tilt_counter_t;
|
|
||||||
|
|
||||||
/// @brief Tilt control structure to manage tilt operations.
|
|
||||||
typedef struct relay_chn_tilt_ctl {
|
|
||||||
relay_chn_ctl_t *chn_ctl; /*!< The relay channel control structure */
|
|
||||||
relay_chn_tilt_cmd_t cmd; /*!< The tilt command in process */
|
|
||||||
relay_chn_tilt_step_t step; /*!< Current tilt step */
|
|
||||||
relay_chn_tilt_timing_t tilt_timing; /*!< Tilt timing structure */
|
|
||||||
relay_chn_tilt_counter_t tilt_counter; /*!< Tilt counter structure */
|
|
||||||
esp_timer_handle_t tilt_timer; /*!< Tilt timer handle */
|
|
||||||
} relay_chn_tilt_ctl_t;
|
|
||||||
|
|
||||||
|
|
||||||
#if RELAY_CHN_COUNT > 1
|
|
||||||
static relay_chn_tilt_ctl_t tilt_ctls[RELAY_CHN_COUNT];
|
|
||||||
#else
|
|
||||||
static relay_chn_tilt_ctl_t tilt_ctl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
esp_err_t relay_chn_tilt_dispatch_cmd(relay_chn_tilt_ctl_t *tilt_ctl, relay_chn_tilt_cmd_t cmd)
|
|
||||||
{
|
|
||||||
if (cmd == RELAY_CHN_TILT_CMD_NONE) return ESP_ERR_INVALID_ARG;
|
|
||||||
|
|
||||||
// Since the event_loop library creates a deep copy of the event data,
|
|
||||||
// and we need to pass the pointer of the relevant tilt control, here we need
|
|
||||||
// to pass the pointer to the pointer of the tilt_control (&tilt_ctl) so that
|
|
||||||
// the pointer value is preserved in the event data.
|
|
||||||
return esp_event_post_to(relay_chn_event_loop,
|
|
||||||
RELAY_CHN_TILT_CMD_EVENT_BASE,
|
|
||||||
cmd,
|
|
||||||
&tilt_ctl,
|
|
||||||
sizeof(tilt_ctl), portMAX_DELAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the required timing before tilting depending on the last run.
|
|
||||||
static uint32_t relay_chn_tilt_get_required_timing_before_tilting(relay_chn_tilt_ctl_t *tilt_ctl, relay_chn_tilt_cmd_t cmd)
|
|
||||||
{
|
|
||||||
relay_chn_cmd_t last_run_cmd = relay_chn_run_info_get_last_run_cmd(tilt_ctl->chn_ctl->run_info);
|
|
||||||
if (cmd == RELAY_CHN_TILT_CMD_FORWARD && last_run_cmd == RELAY_CHN_CMD_REVERSE)
|
|
||||||
return 0;
|
|
||||||
else if (cmd == RELAY_CHN_TILT_CMD_REVERSE && last_run_cmd == RELAY_CHN_CMD_FORWARD)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
uint32_t last_run_cmd_time_ms = relay_chn_run_info_get_last_run_cmd_time_ms(tilt_ctl->chn_ctl->run_info);
|
|
||||||
uint32_t inertia_time_passed_ms = (uint32_t) (esp_timer_get_time() / 1000) - last_run_cmd_time_ms;
|
|
||||||
return RELAY_CHN_OPPOSITE_INERTIA_MS - inertia_time_passed_ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Issue a tilt command to a specific relay channel.
|
|
||||||
static void relay_chn_tilt_issue_cmd(relay_chn_tilt_ctl_t *tilt_ctl, relay_chn_tilt_cmd_t cmd)
|
|
||||||
{
|
|
||||||
if (relay_chn_run_info_get_last_run_cmd(tilt_ctl->chn_ctl->run_info) == RELAY_CHN_CMD_NONE) {
|
|
||||||
// Do not tilt if the channel hasn't been run before
|
|
||||||
ESP_LOGD(TAG, "relay_chn_tilt_issue_cmd: Tilt will not be executed since the channel hasn't been run yet");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tilt_ctl->cmd == cmd) {
|
|
||||||
ESP_LOGD(TAG, "relay_chn_tilt_issue_cmd: There is already a tilt command in progress!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the command that will be processed
|
|
||||||
tilt_ctl->cmd = cmd;
|
|
||||||
switch (tilt_ctl->chn_ctl->state) {
|
|
||||||
case RELAY_CHN_STATE_IDLE:
|
|
||||||
// Relay channel is free, tilt can be issued immediately
|
|
||||||
relay_chn_tilt_dispatch_cmd(tilt_ctl, cmd);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RELAY_CHN_STATE_FORWARD_PENDING:
|
|
||||||
case RELAY_CHN_STATE_REVERSE_PENDING:
|
|
||||||
// Issue a stop command first so that the timer and pending cmd get cleared
|
|
||||||
relay_chn_dispatch_cmd(tilt_ctl->chn_ctl, RELAY_CHN_CMD_STOP);
|
|
||||||
// break not put intentionally
|
|
||||||
case RELAY_CHN_STATE_STOPPED: {
|
|
||||||
// Check if channel needs timing before tilting
|
|
||||||
uint32_t req_timing_ms = relay_chn_tilt_get_required_timing_before_tilting(tilt_ctl, cmd);
|
|
||||||
if (req_timing_ms == 0) {
|
|
||||||
relay_chn_tilt_dispatch_cmd(tilt_ctl, cmd);
|
|
||||||
} else {
|
|
||||||
// Channel needs timing before running tilting action, schedule it
|
|
||||||
tilt_ctl->step = RELAY_CHN_TILT_STEP_PENDING;
|
|
||||||
relay_chn_start_esp_timer_once(tilt_ctl->tilt_timer, req_timing_ms);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case RELAY_CHN_STATE_FORWARD:
|
|
||||||
if (cmd == RELAY_CHN_TILT_CMD_FORWARD) {
|
|
||||||
// Stop the running channel first
|
|
||||||
relay_chn_dispatch_cmd(tilt_ctl->chn_ctl, RELAY_CHN_CMD_STOP);
|
|
||||||
// Schedule for tilting
|
|
||||||
tilt_ctl->step = RELAY_CHN_TILT_STEP_PENDING;
|
|
||||||
relay_chn_start_esp_timer_once(tilt_ctl->tilt_timer, RELAY_CHN_OPPOSITE_INERTIA_MS);
|
|
||||||
} else if (cmd == RELAY_CHN_TILT_CMD_REVERSE) {
|
|
||||||
// Stop the running channel first
|
|
||||||
relay_chn_dispatch_cmd(tilt_ctl->chn_ctl, RELAY_CHN_CMD_STOP);
|
|
||||||
// If the tilt cmd is TILT_REVERSE then dispatch it immediately
|
|
||||||
relay_chn_tilt_dispatch_cmd(tilt_ctl, cmd);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RELAY_CHN_STATE_REVERSE:
|
|
||||||
if (cmd == RELAY_CHN_TILT_CMD_REVERSE) {
|
|
||||||
// Stop the running channel first
|
|
||||||
relay_chn_dispatch_cmd(tilt_ctl->chn_ctl, RELAY_CHN_CMD_STOP);
|
|
||||||
// Schedule for tilting
|
|
||||||
tilt_ctl->step = RELAY_CHN_TILT_STEP_PENDING;
|
|
||||||
relay_chn_start_esp_timer_once(tilt_ctl->tilt_timer, RELAY_CHN_OPPOSITE_INERTIA_MS);
|
|
||||||
} else if (cmd == RELAY_CHN_TILT_CMD_FORWARD) {
|
|
||||||
// Stop the running channel first
|
|
||||||
relay_chn_dispatch_cmd(tilt_ctl->chn_ctl, RELAY_CHN_CMD_STOP);
|
|
||||||
// If the tilt cmd is TILT_FORWARD then dispatch it immediately
|
|
||||||
relay_chn_tilt_dispatch_cmd(tilt_ctl, cmd);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
ESP_LOGD(TAG, "relay_chn_tilt_issue_cmd: Unexpected relay channel state: %s!", relay_chn_state_str(tilt_ctl->chn_ctl->state));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void relay_chn_tilt_issue_auto(relay_chn_tilt_ctl_t *tilt_ctl)
|
|
||||||
{
|
|
||||||
relay_chn_cmd_t last_run_cmd = relay_chn_run_info_get_last_run_cmd(tilt_ctl->chn_ctl->run_info);
|
|
||||||
if (last_run_cmd == RELAY_CHN_CMD_FORWARD || tilt_ctl->chn_ctl->state == RELAY_CHN_STATE_FORWARD) {
|
|
||||||
relay_chn_tilt_issue_cmd(tilt_ctl, RELAY_CHN_TILT_CMD_FORWARD);
|
|
||||||
}
|
|
||||||
else if (last_run_cmd == RELAY_CHN_CMD_REVERSE || tilt_ctl->chn_ctl->state == RELAY_CHN_STATE_REVERSE) {
|
|
||||||
relay_chn_tilt_issue_cmd(tilt_ctl, RELAY_CHN_TILT_CMD_REVERSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if RELAY_CHN_COUNT > 1
|
|
||||||
void relay_chn_tilt_auto(uint8_t chn_id)
|
|
||||||
{
|
|
||||||
if (!relay_chn_is_channel_id_valid(chn_id)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute for all channels
|
|
||||||
if (chn_id == RELAY_CHN_ID_ALL) {
|
|
||||||
for (int i = 0; i < RELAY_CHN_COUNT; i++) {
|
|
||||||
relay_chn_tilt_issue_auto(&tilt_ctls[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Execute for a single channel
|
|
||||||
else {
|
|
||||||
relay_chn_tilt_ctl_t* tilt_ctl = &tilt_ctls[chn_id];
|
|
||||||
relay_chn_tilt_issue_auto(tilt_ctl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void relay_chn_tilt_issue_cmd_on_all_channels(relay_chn_tilt_cmd_t cmd)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < RELAY_CHN_COUNT; i++) {
|
|
||||||
relay_chn_tilt_ctl_t* tilt_ctl = &tilt_ctls[i];
|
|
||||||
relay_chn_tilt_issue_cmd(tilt_ctl, cmd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void relay_chn_tilt_forward(uint8_t chn_id)
|
|
||||||
{
|
|
||||||
if (!relay_chn_is_channel_id_valid(chn_id)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chn_id == RELAY_CHN_ID_ALL)
|
|
||||||
relay_chn_tilt_issue_cmd_on_all_channels(RELAY_CHN_TILT_CMD_FORWARD);
|
|
||||||
else {
|
|
||||||
relay_chn_tilt_ctl_t* tilt_ctl = &tilt_ctls[chn_id];
|
|
||||||
relay_chn_tilt_issue_cmd(tilt_ctl, RELAY_CHN_TILT_CMD_FORWARD);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void relay_chn_tilt_reverse(uint8_t chn_id)
|
|
||||||
{
|
|
||||||
if (!relay_chn_is_channel_id_valid(chn_id)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chn_id == RELAY_CHN_ID_ALL)
|
|
||||||
relay_chn_tilt_issue_cmd_on_all_channels(RELAY_CHN_TILT_CMD_REVERSE);
|
|
||||||
else {
|
|
||||||
relay_chn_tilt_ctl_t* tilt_ctl = &tilt_ctls[chn_id];
|
|
||||||
relay_chn_tilt_issue_cmd(tilt_ctl, RELAY_CHN_TILT_CMD_REVERSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void relay_chn_tilt_stop(uint8_t chn_id)
|
|
||||||
{
|
|
||||||
if (!relay_chn_is_channel_id_valid(chn_id)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chn_id == RELAY_CHN_ID_ALL) {
|
|
||||||
for (int i = 0; i < RELAY_CHN_COUNT; i++) {
|
|
||||||
relay_chn_tilt_dispatch_cmd(&tilt_ctls[i], RELAY_CHN_TILT_CMD_STOP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
relay_chn_tilt_dispatch_cmd(&tilt_ctls[chn_id], RELAY_CHN_TILT_CMD_STOP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#else // RELAY_CHN_COUNT > 1
|
|
||||||
|
|
||||||
void relay_chn_tilt_auto()
|
|
||||||
{
|
|
||||||
relay_chn_tilt_issue_auto(&tilt_ctl);
|
|
||||||
}
|
|
||||||
|
|
||||||
void relay_chn_tilt_forward()
|
|
||||||
{
|
|
||||||
relay_chn_tilt_issue_cmd(&tilt_ctl, RELAY_CHN_TILT_CMD_FORWARD);
|
|
||||||
}
|
|
||||||
|
|
||||||
void relay_chn_tilt_reverse()
|
|
||||||
{
|
|
||||||
relay_chn_tilt_issue_cmd(&tilt_ctl, RELAY_CHN_TILT_CMD_REVERSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void relay_chn_tilt_stop()
|
|
||||||
{
|
|
||||||
relay_chn_tilt_dispatch_cmd(&tilt_ctl, RELAY_CHN_TILT_CMD_STOP);
|
|
||||||
}
|
|
||||||
#endif // RELAY_CHN_COUNT > 1
|
|
||||||
|
|
||||||
static void relay_chn_tilt_set_timing_values(relay_chn_tilt_timing_t *tilt_timing,
|
|
||||||
uint8_t sensitivity,
|
|
||||||
uint32_t run_time_ms,
|
|
||||||
uint32_t pause_time_ms)
|
|
||||||
{
|
|
||||||
tilt_timing->sensitivity = sensitivity;
|
|
||||||
tilt_timing->move_time_ms = run_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)
|
|
||||||
{
|
|
||||||
if (sensitivity >= 100) {
|
|
||||||
relay_chn_tilt_set_timing_values(&tilt_ctl->tilt_timing,
|
|
||||||
100,
|
|
||||||
RELAY_CHN_TILT_RUN_MAX_MS,
|
|
||||||
RELAY_CHN_TILT_PAUSE_MAX_MS);
|
|
||||||
}
|
|
||||||
else if (sensitivity == 0) {
|
|
||||||
relay_chn_tilt_set_timing_values(&tilt_ctl->tilt_timing,
|
|
||||||
0,
|
|
||||||
RELAY_CHN_TILT_RUN_MIN_MS,
|
|
||||||
RELAY_CHN_TILT_PAUSE_MIN_MS);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// 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;
|
|
||||||
tilt_run_time_ms = RELAY_CHN_TILT_RUN_MIN_MS + (sensitivity * (RELAY_CHN_TILT_RUN_MAX_MS - RELAY_CHN_TILT_RUN_MIN_MS) / 100);
|
|
||||||
tilt_pause_time_ms = RELAY_CHN_TILT_PAUSE_MIN_MS + (sensitivity * (RELAY_CHN_TILT_PAUSE_MAX_MS - RELAY_CHN_TILT_PAUSE_MIN_MS) / 100);
|
|
||||||
|
|
||||||
relay_chn_tilt_set_timing_values(&tilt_ctl->tilt_timing,
|
|
||||||
sensitivity,
|
|
||||||
tilt_run_time_ms,
|
|
||||||
tilt_pause_time_ms);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if RELAY_CHN_COUNT > 1
|
|
||||||
void relay_chn_tilt_set_sensitivity(uint8_t chn_id, uint8_t sensitivity)
|
|
||||||
{
|
|
||||||
if (!relay_chn_is_channel_id_valid(chn_id)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chn_id == RELAY_CHN_ID_ALL) {
|
|
||||||
for (int i = 0; i < RELAY_CHN_COUNT; i++) {
|
|
||||||
_relay_chn_tilt_sensitivity_set(&tilt_ctls[i], sensitivity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_relay_chn_tilt_sensitivity_set(&tilt_ctls[chn_id], sensitivity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t relay_chn_tilt_get_sensitivity(uint8_t chn_id, uint8_t *sensitivity, size_t length)
|
|
||||||
{
|
|
||||||
if (!relay_chn_is_channel_id_valid(chn_id)) {
|
|
||||||
return ESP_ERR_INVALID_ARG;
|
|
||||||
}
|
|
||||||
if (sensitivity == NULL) {
|
|
||||||
ESP_LOGD(TAG, "relay_chn_tilt_get_sensitivity: sensitivity is NULL");
|
|
||||||
return ESP_ERR_INVALID_ARG;
|
|
||||||
}
|
|
||||||
if (chn_id == RELAY_CHN_ID_ALL) {
|
|
||||||
if (length < RELAY_CHN_COUNT) {
|
|
||||||
ESP_LOGD(TAG, "relay_chn_tilt_get_sensitivity: length is too short to store all sensitivity values");
|
|
||||||
return ESP_ERR_INVALID_ARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < RELAY_CHN_COUNT; i++) {
|
|
||||||
sensitivity[i] = tilt_ctls[i].tilt_timing.sensitivity;
|
|
||||||
}
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
*sensitivity = tilt_ctls[chn_id].tilt_timing.sensitivity;
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
void relay_chn_tilt_set_sensitivity(uint8_t sensitivity)
|
|
||||||
{
|
|
||||||
_relay_chn_tilt_sensitivity_set(&tilt_ctl, sensitivity);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t relay_chn_tilt_get_sensitivity()
|
|
||||||
{
|
|
||||||
return tilt_ctl.tilt_timing.sensitivity;
|
|
||||||
}
|
|
||||||
#endif // RELAY_CHN_COUNT > 1
|
|
||||||
|
|
||||||
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_reverse_count = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Update tilt count automatically and return the current value.
|
|
||||||
*
|
|
||||||
* This helper function updates the relevant tilt count depending on the
|
|
||||||
* last run info and helps the tilt module in deciding whether the requested
|
|
||||||
* tilt should execute or not.
|
|
||||||
* This is useful to control reverse tilting particularly. For example:
|
|
||||||
* - If the channel's last run was FORWARD and a TILT_FORWARD is requested,
|
|
||||||
* then the tilt counter will count up on the
|
|
||||||
* relay_chn_tilt_counter_type::tilt_forward_count and the function will
|
|
||||||
* return the actual count.
|
|
||||||
* - If the channel's last run was FORWARD and a TILT_REVERSE is requested,
|
|
||||||
* then the relay_chn_tilt_counter_type::tilt_forward_count will be checked
|
|
||||||
* against zero first, and then it will count down and return the actual count
|
|
||||||
* if it is greater than 0, else the function will return 0.
|
|
||||||
* - If the tilt command is irrelevant then the function will return 0.
|
|
||||||
* - If the last run is irrelevant then the function will return 0.
|
|
||||||
*
|
|
||||||
* @param tilt_ctl The relay channel handle.
|
|
||||||
* @return uint32_t The actual value of the relevant counter.
|
|
||||||
* @return 0 if:
|
|
||||||
* - related counter is already 0.
|
|
||||||
* - tilt command is irrelevant.
|
|
||||||
* - last run info is irrelevant.
|
|
||||||
*/
|
|
||||||
static uint32_t relay_chn_tilt_count_update(relay_chn_tilt_ctl_t *tilt_ctl)
|
|
||||||
{
|
|
||||||
relay_chn_cmd_t last_run_cmd = relay_chn_run_info_get_last_run_cmd(tilt_ctl->chn_ctl->run_info);
|
|
||||||
if (last_run_cmd == RELAY_CHN_CMD_FORWARD) {
|
|
||||||
if (tilt_ctl->cmd == RELAY_CHN_TILT_CMD_FORWARD) {
|
|
||||||
return ++tilt_ctl->tilt_counter.tilt_forward_count;
|
|
||||||
}
|
|
||||||
else if (tilt_ctl->cmd == RELAY_CHN_TILT_CMD_REVERSE) {
|
|
||||||
if (tilt_ctl->tilt_counter.tilt_forward_count > 0) {
|
|
||||||
--tilt_ctl->tilt_counter.tilt_forward_count;
|
|
||||||
// Still should do one more move, return non-zero value
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
relay_chn_tilt_reset_count(tilt_ctl);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (last_run_cmd == RELAY_CHN_CMD_REVERSE) {
|
|
||||||
if (tilt_ctl->cmd == RELAY_CHN_TILT_CMD_REVERSE) {
|
|
||||||
return ++tilt_ctl->tilt_counter.tilt_reverse_count;
|
|
||||||
}
|
|
||||||
else if (tilt_ctl->cmd == RELAY_CHN_TILT_CMD_FORWARD) {
|
|
||||||
if (tilt_ctl->tilt_counter.tilt_reverse_count > 0) {
|
|
||||||
--tilt_ctl->tilt_counter.tilt_reverse_count;
|
|
||||||
// Still should do one more move, return non-zero value
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
relay_chn_tilt_reset_count(tilt_ctl);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void relay_chn_tilt_execute_stop(relay_chn_tilt_ctl_t *tilt_ctl)
|
|
||||||
{
|
|
||||||
// Stop the channel's timer if active
|
|
||||||
esp_timer_stop(tilt_ctl->tilt_timer);
|
|
||||||
// Invalidate tilt cmd and step
|
|
||||||
tilt_ctl->cmd = RELAY_CHN_TILT_CMD_NONE;
|
|
||||||
tilt_ctl->step = RELAY_CHN_TILT_STEP_NONE;
|
|
||||||
// Stop the channel
|
|
||||||
if (relay_chn_output_stop(tilt_ctl->chn_ctl->output) != ESP_OK) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void relay_chn_tilt_execute_forward(relay_chn_tilt_ctl_t *tilt_ctl)
|
|
||||||
{
|
|
||||||
if (relay_chn_output_reverse(tilt_ctl->chn_ctl->output) != ESP_OK) {
|
|
||||||
ESP_LOGE(TAG, "relay_chn_tilt_execute_forward: Failed to output reverse for relay channel #%d!", tilt_ctl->chn_ctl->id);
|
|
||||||
// Stop tilting because of the error
|
|
||||||
relay_chn_tilt_dispatch_cmd(tilt_ctl, RELAY_CHN_TILT_CMD_STOP);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Set the move time timer
|
|
||||||
relay_chn_start_esp_timer_once(tilt_ctl->tilt_timer, tilt_ctl->tilt_timing.move_time_ms);
|
|
||||||
// Set to pause step
|
|
||||||
tilt_ctl->step = RELAY_CHN_TILT_STEP_PAUSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void relay_chn_tilt_execute_reverse(relay_chn_tilt_ctl_t *tilt_ctl)
|
|
||||||
{
|
|
||||||
if (relay_chn_output_forward(tilt_ctl->chn_ctl->output) != ESP_OK) {
|
|
||||||
ESP_LOGE(TAG, "relay_chn_tilt_execute_reverse: Failed to output forward for relay channel #%d!", tilt_ctl->chn_ctl->id);
|
|
||||||
// Stop tilting because of the error
|
|
||||||
relay_chn_tilt_dispatch_cmd(tilt_ctl, RELAY_CHN_TILT_CMD_STOP);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Set the move time timer
|
|
||||||
relay_chn_start_esp_timer_once(tilt_ctl->tilt_timer, tilt_ctl->tilt_timing.move_time_ms);
|
|
||||||
// Set to pause step
|
|
||||||
tilt_ctl->step = RELAY_CHN_TILT_STEP_PAUSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void relay_chn_tilt_execute_pause(relay_chn_tilt_ctl_t *tilt_ctl)
|
|
||||||
{
|
|
||||||
// Pause the channel
|
|
||||||
if (relay_chn_output_stop(tilt_ctl->chn_ctl->output) != ESP_OK) {
|
|
||||||
ESP_LOGE(TAG, "relay_chn_tilt_execute_pause: Failed to output stop for relay channel #%d!", tilt_ctl->chn_ctl->id);
|
|
||||||
// Stop tilting because of the error
|
|
||||||
relay_chn_tilt_dispatch_cmd(tilt_ctl, RELAY_CHN_TILT_CMD_STOP);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the tilt counter before the next move and expect the return value to be greater than 0
|
|
||||||
if (relay_chn_tilt_count_update(tilt_ctl) == 0) {
|
|
||||||
ESP_LOGD(TAG, "relay_chn_tilt_execute_pause: Relay channel cannot tilt anymore");
|
|
||||||
// Stop tilting since the tilting limit has been reached
|
|
||||||
relay_chn_tilt_dispatch_cmd(tilt_ctl, RELAY_CHN_TILT_CMD_STOP);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the pause time timer
|
|
||||||
relay_chn_start_esp_timer_once(tilt_ctl->tilt_timer, tilt_ctl->tilt_timing.pause_time_ms);
|
|
||||||
// Set to move step
|
|
||||||
tilt_ctl->step = RELAY_CHN_TILT_STEP_MOVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void relay_chn_tilt_event_handler(void *handler_arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
|
|
||||||
{
|
|
||||||
relay_chn_tilt_ctl_t* tilt_ctl = *(relay_chn_tilt_ctl_t**) event_data;
|
|
||||||
ESP_RETURN_VOID_ON_FALSE(tilt_ctl != NULL, TAG, "event_data is NULL");
|
|
||||||
ESP_LOGD(TAG, "relay_chn_event_handler: Command: %s", relay_chn_cmd_str(event_id));
|
|
||||||
|
|
||||||
switch(event_id) {
|
|
||||||
case RELAY_CHN_TILT_CMD_STOP:
|
|
||||||
relay_chn_tilt_execute_stop(tilt_ctl);
|
|
||||||
break;
|
|
||||||
case RELAY_CHN_TILT_CMD_FORWARD:
|
|
||||||
relay_chn_tilt_execute_forward(tilt_ctl);
|
|
||||||
// Update channel state
|
|
||||||
relay_chn_update_state(tilt_ctl->chn_ctl, RELAY_CHN_STATE_TILT_FORWARD);
|
|
||||||
break;
|
|
||||||
case RELAY_CHN_TILT_CMD_REVERSE:
|
|
||||||
relay_chn_tilt_execute_reverse(tilt_ctl);
|
|
||||||
// Update channel state
|
|
||||||
relay_chn_update_state(tilt_ctl->chn_ctl, RELAY_CHN_STATE_TILT_REVERSE);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ESP_LOGW(TAG, "Unexpected relay channel tilt command: %ld!", event_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Timer callback for the relay_chn_tilt_control_t::tilt_timer
|
|
||||||
static void relay_chn_tilt_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_timer_cb: event_data is NULL");
|
|
||||||
|
|
||||||
switch (tilt_ctl->step)
|
|
||||||
{
|
|
||||||
case RELAY_CHN_TILT_STEP_MOVE:
|
|
||||||
if (tilt_ctl->cmd == RELAY_CHN_TILT_CMD_FORWARD) {
|
|
||||||
relay_chn_tilt_execute_forward(tilt_ctl);
|
|
||||||
}
|
|
||||||
else if (tilt_ctl->cmd == RELAY_CHN_TILT_CMD_REVERSE) {
|
|
||||||
relay_chn_tilt_execute_reverse(tilt_ctl);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RELAY_CHN_TILT_STEP_PAUSE:
|
|
||||||
relay_chn_tilt_execute_pause(tilt_ctl);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RELAY_CHN_TILT_STEP_PENDING:
|
|
||||||
// Just dispatch the pending tilt command
|
|
||||||
relay_chn_tilt_dispatch_cmd(tilt_ctl, tilt_ctl->cmd);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t relay_chn_tilt_ctl_init(relay_chn_tilt_ctl_t *tilt_ctl, relay_chn_ctl_t *chn_ctl)
|
|
||||||
{
|
|
||||||
tilt_ctl->cmd = RELAY_CHN_TILT_CMD_NONE;
|
|
||||||
tilt_ctl->step = RELAY_CHN_TILT_STEP_NONE;
|
|
||||||
tilt_ctl->tilt_timing.sensitivity = RELAY_CHN_TILT_DEFAULT_SENSITIVITY;
|
|
||||||
tilt_ctl->tilt_timing.move_time_ms = RELAY_CHN_TILT_DEFAULT_RUN_MS;
|
|
||||||
tilt_ctl->tilt_timing.pause_time_ms = RELAY_CHN_TILT_DEFAULT_PAUSE_MS;
|
|
||||||
relay_chn_tilt_reset_count(tilt_ctl);
|
|
||||||
|
|
||||||
tilt_ctl->chn_ctl = chn_ctl;
|
|
||||||
tilt_ctl->chn_ctl->tilt_ctl = tilt_ctl; //
|
|
||||||
|
|
||||||
// Create tilt timer for the channel
|
|
||||||
char timer_name[32];
|
|
||||||
snprintf(timer_name, sizeof(timer_name), "relay_chn_%2d_tilt_timer", chn_ctl->id);
|
|
||||||
esp_timer_create_args_t timer_args = {
|
|
||||||
.callback = relay_chn_tilt_timer_cb,
|
|
||||||
.arg = tilt_ctl,
|
|
||||||
.name = timer_name
|
|
||||||
};
|
|
||||||
return esp_timer_create(&timer_args, &tilt_ctl->tilt_timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t relay_chn_tilt_init(relay_chn_ctl_t *chn_ctls)
|
|
||||||
{
|
|
||||||
#if RELAY_CHN_COUNT > 1
|
|
||||||
for (int i = 0; i < RELAY_CHN_COUNT; i++) {
|
|
||||||
relay_chn_tilt_ctl_init(&tilt_ctls[i], &chn_ctls[i]);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
relay_chn_tilt_ctl_init(&tilt_ctl, chn_ctls);
|
|
||||||
#endif // RELAY_CHN_COUNT > 1
|
|
||||||
|
|
||||||
return esp_event_handler_register_with(relay_chn_event_loop,
|
|
||||||
RELAY_CHN_TILT_CMD_EVENT_BASE,
|
|
||||||
ESP_EVENT_ANY_ID,
|
|
||||||
relay_chn_tilt_event_handler, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void relay_chn_tilt_ctl_deinit(relay_chn_tilt_ctl_t *tilt_ctl)
|
|
||||||
{
|
|
||||||
if (tilt_ctl->tilt_timer != NULL) {
|
|
||||||
esp_timer_delete(tilt_ctl->tilt_timer);
|
|
||||||
tilt_ctl->tilt_timer = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void relay_chn_tilt_deinit()
|
|
||||||
{
|
|
||||||
#if RELAY_CHN_COUNT > 1
|
|
||||||
for (int i = 0; i < RELAY_CHN_COUNT; i++) {
|
|
||||||
relay_chn_tilt_ctl_deinit(&tilt_ctls[i]);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
relay_chn_tilt_ctl_deinit(&tilt_ctl);
|
|
||||||
#endif // RELAY_CHN_COUNT > 1
|
|
||||||
esp_event_handler_unregister_with(relay_chn_event_loop,
|
|
||||||
RELAY_CHN_TILT_CMD_EVENT_BASE,
|
|
||||||
ESP_EVENT_ANY_ID,
|
|
||||||
relay_chn_tilt_event_handler);
|
|
||||||
}
|
|
||||||
@@ -11,10 +11,19 @@ set(EXTRA_COMPONENT_DIRS "../")
|
|||||||
set(COMPONENTS main)
|
set(COMPONENTS main)
|
||||||
|
|
||||||
# Include ESP-IDF project build system
|
# Include ESP-IDF project build system
|
||||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
# include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
|
||||||
|
file(TO_NATIVE_PATH "$ENV{IDF_PATH}/tools/cmake/project.cmake" _project_path)
|
||||||
|
|
||||||
# Inject the test tag into the build
|
# Inject the test tag into the build
|
||||||
add_compile_definitions(RELAY_CHN_UNITY_TEST_GROUP_TAG=\"$ENV{RELAY_CHN_UNITY_TEST_GROUP_TAG}\")
|
add_compile_definitions(RELAY_CHN_UNITY_TEST_GROUP_TAG=\"$ENV{RELAY_CHN_UNITY_TEST_GROUP_TAG}\")
|
||||||
|
|
||||||
|
include(${_project_path})
|
||||||
|
|
||||||
# Define the name of this project
|
# Define the name of this project
|
||||||
project(relay_chn_test)
|
project(relay_chn_test)
|
||||||
|
|
||||||
|
file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/coverage_report" _coverage_path)
|
||||||
|
|
||||||
|
idf_create_coverage_report(${_coverage_path})
|
||||||
|
idf_clean_coverage_report(${_coverage_path})
|
||||||
@@ -1,29 +1,27 @@
|
|||||||
# === These files must be included in any case ===
|
# === These files must be included in any case ===
|
||||||
set(srcs "test_common.c"
|
set(srcs "test_common.c"
|
||||||
"test_app_main.c")
|
"test_app_main.c"
|
||||||
|
"test_relay_chn_core.c"
|
||||||
# === Selective compilation based on channel count ===
|
"test_relay_chn_listener.c")
|
||||||
if(CONFIG_RELAY_CHN_COUNT GREATER 1)
|
|
||||||
list(APPEND srcs "test_relay_chn_core_multi.c"
|
|
||||||
"test_relay_chn_listener_multi.c")
|
|
||||||
else()
|
|
||||||
list(APPEND srcs "test_relay_chn_core_single.c"
|
|
||||||
"test_relay_chn_listener_single.c")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CONFIG_RELAY_CHN_ENABLE_TILTING)
|
if(CONFIG_RELAY_CHN_ENABLE_TILTING)
|
||||||
if(CONFIG_RELAY_CHN_COUNT GREATER 1)
|
list(APPEND srcs "test_relay_chn_tilt.c")
|
||||||
list(APPEND srcs "test_relay_chn_tilt_multi.c")
|
|
||||||
else()
|
|
||||||
list(APPEND srcs "test_relay_chn_tilt_single.c")
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "srcs=${srcs}")
|
||||||
|
|
||||||
# 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 "."
|
||||||
REQUIRES unity relay_chn
|
REQUIRES unity relay_chn app_trace
|
||||||
WHOLE_ARCHIVE
|
WHOLE_ARCHIVE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set_source_files_properties(
|
||||||
|
"test_common.c"
|
||||||
|
"test_app_main.c"
|
||||||
|
"test_relay_chn_core.c"
|
||||||
|
"test_relay_chn_listener.c"
|
||||||
|
PROPERTIES COMPILE_FLAGS --coverage)
|
||||||
@@ -2,38 +2,16 @@
|
|||||||
|
|
||||||
const char *TEST_TAG = "RELAY_CHN_TEST";
|
const char *TEST_TAG = "RELAY_CHN_TEST";
|
||||||
|
|
||||||
const uint8_t relay_chn_count = CONFIG_RELAY_CHN_COUNT;
|
// GPIO eşlemesi (örn: GPIO_NUM_4 vs GPIO_NUM_5)
|
||||||
|
const gpio_num_t gpio_map[] = {
|
||||||
|
GPIO_NUM_4, GPIO_NUM_5, GPIO_NUM_18, GPIO_NUM_19
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t gpio_count = sizeof(gpio_map) / sizeof(gpio_map[0]);
|
||||||
|
const uint8_t relay_chn_count = gpio_count / 2;
|
||||||
|
|
||||||
|
// Konfigürasyon tabanlı inertia süresi
|
||||||
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 toleransı
|
||||||
|
|
||||||
bool g_is_component_initialized = false;
|
bool g_is_component_initialized = false;
|
||||||
|
|
||||||
// Test-wide GPIO map
|
|
||||||
#if CONFIG_RELAY_CHN_COUNT > 1
|
|
||||||
const uint8_t gpio_map[] = {
|
|
||||||
0, 1,
|
|
||||||
2, 3
|
|
||||||
#if CONFIG_RELAY_CHN_COUNT > 2
|
|
||||||
, 4, 5
|
|
||||||
#if CONFIG_RELAY_CHN_COUNT > 3
|
|
||||||
, 6, 7
|
|
||||||
#if CONFIG_RELAY_CHN_COUNT > 4
|
|
||||||
, 8, 9
|
|
||||||
#if CONFIG_RELAY_CHN_COUNT > 5
|
|
||||||
, 10, 11
|
|
||||||
#if CONFIG_RELAY_CHN_COUNT > 6
|
|
||||||
, 12, 13
|
|
||||||
#if CONFIG_RELAY_CHN_COUNT > 7
|
|
||||||
, 14, 15
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
const uint8_t gpio_map[] = {4, 5};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const uint8_t gpio_count = sizeof(gpio_map) / sizeof(gpio_map[0]);
|
|
||||||
@@ -3,21 +3,23 @@
|
|||||||
#include <string.h> // For memset
|
#include <string.h> // For memset
|
||||||
#include "unity.h"
|
#include "unity.h"
|
||||||
#include "relay_chn.h"
|
#include "relay_chn.h"
|
||||||
|
#include "driver/gpio.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
|
|
||||||
// Test log tag
|
// Test log tag
|
||||||
extern const char *TEST_TAG;
|
extern const char *TEST_TAG;
|
||||||
|
|
||||||
// GPIO configurations
|
// GPIO konfigürasyonları
|
||||||
extern const uint8_t gpio_map[];
|
extern const gpio_num_t gpio_map[];
|
||||||
extern const uint8_t gpio_count;
|
extern const uint8_t gpio_count;
|
||||||
extern const uint8_t relay_chn_count;
|
extern const uint8_t relay_chn_count;
|
||||||
|
|
||||||
// Config variables for tests
|
// Config parametreleri
|
||||||
extern const uint32_t opposite_inertia_ms;
|
extern const uint32_t opposite_inertia_ms;
|
||||||
extern const uint32_t test_delay_margin_ms;
|
extern const uint32_t test_delay_margin_ms;
|
||||||
|
|
||||||
// Init state
|
// Init durumu
|
||||||
extern bool g_is_component_initialized;
|
extern bool g_is_component_initialized;
|
||||||
|
|||||||
@@ -13,20 +13,20 @@ TEST_CASE("relay_chn_create handles invalid arguments", "[relay_chn][core]")
|
|||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, relay_chn_create(gpio_map, 1));
|
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, relay_chn_create(gpio_map, 1));
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, relay_chn_create(gpio_map, 0));
|
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, relay_chn_create(gpio_map, 0));
|
||||||
|
|
||||||
// 3. Test with invalid GPIO numbers (127 is an invalid GPIO for output)
|
// 3. Test with invalid GPIO numbers (GPIO_NUM_MAX is an invalid GPIO for output)
|
||||||
uint8_t invalid_gpio_map[] = {4, 127, 18, 19};
|
gpio_num_t invalid_gpio_map[] = {GPIO_NUM_4, GPIO_NUM_MAX, GPIO_NUM_18, GPIO_NUM_19};
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, relay_chn_create(invalid_gpio_map, gpio_count));
|
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, relay_chn_create(invalid_gpio_map, gpio_count));
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Basic Functionality Tests ---
|
// --- Basic Functionality Tests ---
|
||||||
|
|
||||||
// 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_FREE
|
||||||
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));
|
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
|
||||||
g_is_component_initialized = true;
|
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_FREE, relay_chn_get_state(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ TEST_CASE("Run forward does nothing if channel id is invalid", "[relay_chn][core
|
|||||||
relay_chn_run_forward(invalid_id); // relay_chn_run_forward returns void
|
relay_chn_run_forward(invalid_id); // relay_chn_run_forward returns void
|
||||||
// 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));
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state(i));
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FREE, relay_chn_get_state(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ TEST_CASE("Run reverse does nothing if channel id is invalid", "[relay_chn][core
|
|||||||
// Call run_reverse with an invalid ID
|
// Call run_reverse with an invalid ID
|
||||||
relay_chn_run_reverse(invalid_id);
|
relay_chn_run_reverse(invalid_id);
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state(i));
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FREE, relay_chn_get_state(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,13 +127,13 @@ TEST_CASE("stop with ID_ALL stops all running channels", "[relay_chn][core][id_a
|
|||||||
|
|
||||||
// 3. Verify all channels have transitioned to the FREE state
|
// 3. Verify all channels have transitioned to the FREE state
|
||||||
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_FREE, relay_chn_get_state(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 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_FREE
|
||||||
// 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));
|
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
|
||||||
@@ -151,9 +151,9 @@ TEST_CASE("Relay channels stop and update to FREE state", "[relay_chn][core]") {
|
|||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_STOPPED, relay_chn_get_state(i));
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_STOPPED, relay_chn_get_state(i));
|
||||||
|
|
||||||
// Then, wait for the inertia period for it to transition to RELAY_CHN_STATE_IDLE
|
// Then, wait for the inertia period for it to transition to RELAY_CHN_STATE_FREE
|
||||||
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
|
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state(i));
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FREE, relay_chn_get_state(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,7 +203,7 @@ TEST_CASE("Multiple channels can operate independently", "[relay_chn][core]") {
|
|||||||
relay_chn_run_forward(0); // relay_chn_run_forward returns void
|
relay_chn_run_forward(0); // relay_chn_run_forward returns void
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD, relay_chn_get_state(0));
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD, relay_chn_get_state(0));
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state(1)); // Other channel should not be affected
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FREE, relay_chn_get_state(1)); // Other channel should not be affected
|
||||||
|
|
||||||
// Start Channel 1 in reverse direction
|
// Start Channel 1 in reverse direction
|
||||||
relay_chn_run_reverse(1); // relay_chn_run_reverse returns void
|
relay_chn_run_reverse(1); // relay_chn_run_reverse returns void
|
||||||
@@ -214,14 +214,14 @@ TEST_CASE("Multiple channels can operate independently", "[relay_chn][core]") {
|
|||||||
// Stop Channel 0 and wait for it to become FREE
|
// Stop Channel 0 and wait for it to become FREE
|
||||||
relay_chn_stop(0); // relay_chn_stop returns void
|
relay_chn_stop(0); // relay_chn_stop returns void
|
||||||
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
|
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state(0));
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FREE, relay_chn_get_state(0));
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_REVERSE, relay_chn_get_state(1)); // Other channel should continue running
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_REVERSE, relay_chn_get_state(1)); // Other channel should continue running
|
||||||
|
|
||||||
// Stop Channel 1 and wait for it to become FREE
|
// Stop Channel 1 and wait for it to become FREE
|
||||||
relay_chn_stop(1); // relay_chn_stop returns void
|
relay_chn_stop(1); // relay_chn_stop returns void
|
||||||
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
|
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state(0));
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FREE, relay_chn_get_state(0));
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state(1));
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FREE, relay_chn_get_state(1));
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGW("TEST", "Skipping 'Multiple channels can operate independently' test: Not enough channels available.");
|
ESP_LOGW("TEST", "Skipping 'Multiple channels can operate independently' test: Not enough channels available.");
|
||||||
}
|
}
|
||||||
@@ -301,7 +301,7 @@ TEST_CASE("Running in same direction does not incur inertia", "[relay_chn][core]
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TEST_CASE: Test transition from FREE state to running (no inertia expected)
|
// TEST_CASE: Test transition from FREE state to running (no inertia expected)
|
||||||
// Scenario: RELAY_CHN_STATE_IDLE -> (relay_chn_run_forward) -> RELAY_CHN_STATE_FORWARD
|
// Scenario: RELAY_CHN_STATE_FREE -> (relay_chn_run_forward) -> RELAY_CHN_STATE_FORWARD
|
||||||
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;
|
||||||
|
|
||||||
@@ -309,7 +309,7 @@ TEST_CASE("FREE to Running transition without inertia", "[relay_chn][core][inert
|
|||||||
g_is_component_initialized = true;
|
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_FREE, relay_chn_get_state(ch));
|
||||||
|
|
||||||
// Start in forward direction
|
// 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
|
||||||
@@ -388,7 +388,7 @@ TEST_CASE("Flipping a running channel stops it and flips direction", "[relay_chn
|
|||||||
|
|
||||||
// 4. Wait for the flip inertia to pass, after which it should be FREE and FLIPPED
|
// 4. Wait for the flip inertia to pass, after which it should be FREE and FLIPPED
|
||||||
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
|
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state(ch));
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FREE, relay_chn_get_state(ch));
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_DIRECTION_FLIPPED, relay_chn_get_direction(ch));
|
TEST_ASSERT_EQUAL(RELAY_CHN_DIRECTION_FLIPPED, relay_chn_get_direction(ch));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,204 +0,0 @@
|
|||||||
#include "test_common.h"
|
|
||||||
|
|
||||||
|
|
||||||
// --- Initialization Tests ---
|
|
||||||
|
|
||||||
TEST_CASE("relay_chn_create handles invalid arguments", "[relay_chn][core]")
|
|
||||||
{
|
|
||||||
// 1. Test with NULL gpio_map
|
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, relay_chn_create(NULL, gpio_count));
|
|
||||||
|
|
||||||
// 2. Test with incorrect gpio_count (must be RELAY_CHN_COUNT * 2)
|
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, relay_chn_create(gpio_map, gpio_count - 1));
|
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, relay_chn_create(gpio_map, 1));
|
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, relay_chn_create(gpio_map, 0));
|
|
||||||
|
|
||||||
// 3. Test with invalid GPIO numbers (GPIO_NUM_MAX is an invalid GPIO for output)
|
|
||||||
uint8_t invalid_gpio_map[] = {4, 127};
|
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, relay_chn_create(invalid_gpio_map, gpio_count));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Basic Functionality Tests ---
|
|
||||||
|
|
||||||
// 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_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_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_ESP_OK(relay_chn_create(gpio_map, gpio_count));
|
|
||||||
g_is_component_initialized = true;
|
|
||||||
|
|
||||||
relay_chn_run_forward();
|
|
||||||
// Short delay for state to update
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD, relay_chn_get_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_ESP_OK(relay_chn_create(gpio_map, gpio_count));
|
|
||||||
g_is_component_initialized = true;
|
|
||||||
|
|
||||||
relay_chn_run_reverse(); // relay_chn_run_reverse returns void
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_REVERSE, relay_chn_get_state());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
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
|
|
||||||
relay_chn_run_forward();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD, relay_chn_get_state());
|
|
||||||
|
|
||||||
// Now, issue the stop command
|
|
||||||
relay_chn_stop(); // relay_chn_stop returns void
|
|
||||||
// Immediately after stop, state should be STOPPED
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_STOPPED, relay_chn_get_state());
|
|
||||||
|
|
||||||
// Then, wait for the inertia period for it to transition to RELAY_CHN_STATE_IDLE
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ### Inertia and State Transition Tests
|
|
||||||
|
|
||||||
// This section specifically targets the inertia periods and complex state transitions as per the component's logic.
|
|
||||||
|
|
||||||
// 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
|
|
||||||
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
|
|
||||||
relay_chn_run_forward();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms)); // Short delay for state stabilization
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD, relay_chn_get_state());
|
|
||||||
|
|
||||||
// 2. Issue reverse command
|
|
||||||
relay_chn_run_reverse(); // relay_chn_run_reverse returns void
|
|
||||||
// Immediately after the command, the motor should be stopped
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_REVERSE_PENDING, relay_chn_get_state());
|
|
||||||
|
|
||||||
// Wait for the inertia period (after which the reverse command will be dispatched)
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_REVERSE, relay_chn_get_state()); // Should now be in reverse state
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
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
|
|
||||||
relay_chn_run_reverse(); // relay_chn_run_reverse returns void
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_REVERSE, relay_chn_get_state());
|
|
||||||
|
|
||||||
// 2. Issue forward command
|
|
||||||
relay_chn_run_forward();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD_PENDING, relay_chn_get_state());
|
|
||||||
|
|
||||||
// Wait for inertia
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD, relay_chn_get_state());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
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
|
|
||||||
relay_chn_run_forward();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD, relay_chn_get_state());
|
|
||||||
|
|
||||||
// 2. Issue the same forward command again
|
|
||||||
relay_chn_run_forward();
|
|
||||||
// As per the code, is_direction_opposite_to_current_motion should return false, so no inertia.
|
|
||||||
// Just a short delay to check state remains the same.
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD, relay_chn_get_state());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
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
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state());
|
|
||||||
|
|
||||||
// Start in forward direction
|
|
||||||
relay_chn_run_forward();
|
|
||||||
// No inertia is expected when starting from IDLE state.
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD, relay_chn_get_state());
|
|
||||||
}
|
|
||||||
|
|
||||||
// ### Direction Flipping Tests
|
|
||||||
|
|
||||||
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
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_DIRECTION_DEFAULT, relay_chn_get_direction());
|
|
||||||
|
|
||||||
// 2. Flip the direction
|
|
||||||
relay_chn_flip_direction();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms)); // Wait for flip inertia
|
|
||||||
|
|
||||||
// 3. Verify direction is flipped
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_DIRECTION_FLIPPED, relay_chn_get_direction());
|
|
||||||
|
|
||||||
// 4. Flip back
|
|
||||||
relay_chn_flip_direction();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms)); // Wait for flip inertia
|
|
||||||
|
|
||||||
// 5. Verify direction is back to default
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_DIRECTION_DEFAULT, relay_chn_get_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
|
|
||||||
relay_chn_run_forward();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD, relay_chn_get_state());
|
|
||||||
|
|
||||||
// 2. Flip the direction while running
|
|
||||||
relay_chn_flip_direction();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms)); // Give time for events to process
|
|
||||||
|
|
||||||
// 3. The channel should stop as part of the flip process
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_STOPPED, relay_chn_get_state());
|
|
||||||
|
|
||||||
// 4. Wait for the flip inertia to pass, after which it should be IDLE and FLIPPED
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state());
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_DIRECTION_FLIPPED, relay_chn_get_direction());
|
|
||||||
}
|
|
||||||
@@ -52,7 +52,7 @@ TEST_CASE("Listener is called on state change", "[relay_chn][listener]") {
|
|||||||
// 3. Verify the listener was called with correct parameters
|
// 3. Verify the listener was called with correct parameters
|
||||||
TEST_ASSERT_EQUAL(1, listener1_info.call_count);
|
TEST_ASSERT_EQUAL(1, listener1_info.call_count);
|
||||||
TEST_ASSERT_EQUAL(ch, listener1_info.chn_id);
|
TEST_ASSERT_EQUAL(ch, listener1_info.chn_id);
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, listener1_info.old_state);
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FREE, listener1_info.old_state);
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD, listener1_info.new_state);
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD, listener1_info.new_state);
|
||||||
|
|
||||||
// 4. Unregister to clean up
|
// 4. Unregister to clean up
|
||||||
@@ -96,12 +96,12 @@ TEST_CASE("Multiple listeners are called on state change", "[relay_chn][listener
|
|||||||
|
|
||||||
// 3. Verify listener 1 was called correctly
|
// 3. Verify listener 1 was called correctly
|
||||||
TEST_ASSERT_EQUAL(1, listener1_info.call_count);
|
TEST_ASSERT_EQUAL(1, listener1_info.call_count);
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, listener1_info.old_state);
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FREE, listener1_info.old_state);
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD, listener1_info.new_state);
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD, listener1_info.new_state);
|
||||||
|
|
||||||
// 4. Verify listener 2 was also called correctly
|
// 4. Verify listener 2 was also called correctly
|
||||||
TEST_ASSERT_EQUAL(1, listener2_info.call_count);
|
TEST_ASSERT_EQUAL(1, listener2_info.call_count);
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, listener2_info.old_state);
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FREE, listener2_info.old_state);
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD, listener2_info.new_state);
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD, listener2_info.new_state);
|
||||||
|
|
||||||
// 5. Clean up
|
// 5. Clean up
|
||||||
@@ -1,130 +0,0 @@
|
|||||||
#include "test_common.h"
|
|
||||||
|
|
||||||
|
|
||||||
// --- Listener Test Globals ---
|
|
||||||
typedef struct {
|
|
||||||
relay_chn_state_t old_state;
|
|
||||||
relay_chn_state_t new_state;
|
|
||||||
int call_count;
|
|
||||||
} listener_callback_info_t;
|
|
||||||
|
|
||||||
static listener_callback_info_t listener1_info;
|
|
||||||
static listener_callback_info_t listener2_info;
|
|
||||||
|
|
||||||
// --- Listener Test Helper Functions ---
|
|
||||||
|
|
||||||
// Clear the memory from possible garbage values
|
|
||||||
static void reset_listener_info(listener_callback_info_t* info) {
|
|
||||||
memset(info, 0, sizeof(listener_callback_info_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void test_listener_1(uint8_t chn_id, relay_chn_state_t old_state, relay_chn_state_t new_state) {
|
|
||||||
/* Just ignore the channel id */
|
|
||||||
listener1_info.old_state = old_state;
|
|
||||||
listener1_info.new_state = new_state;
|
|
||||||
listener1_info.call_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void test_listener_2(uint8_t chn_id, relay_chn_state_t old_state, relay_chn_state_t new_state) {
|
|
||||||
/* Just ignore the channel id */
|
|
||||||
listener2_info.old_state = old_state;
|
|
||||||
listener2_info.new_state = new_state;
|
|
||||||
listener2_info.call_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ### Listener Functionality Tests
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
// 1. Register the listener
|
|
||||||
TEST_ESP_OK(relay_chn_register_listener(test_listener_1));
|
|
||||||
|
|
||||||
// 2. Trigger a state change
|
|
||||||
relay_chn_run_forward();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms)); // Allow event to be processed
|
|
||||||
|
|
||||||
// 3. Verify the listener was called with correct parameters
|
|
||||||
TEST_ASSERT_EQUAL(1, listener1_info.call_count);
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, listener1_info.old_state);
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD, listener1_info.new_state);
|
|
||||||
|
|
||||||
// 4. Unregister to clean up
|
|
||||||
relay_chn_unregister_listener(test_listener_1);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
// 1. Register and then immediately unregister the listener
|
|
||||||
TEST_ESP_OK(relay_chn_register_listener(test_listener_1));
|
|
||||||
relay_chn_unregister_listener(test_listener_1);
|
|
||||||
|
|
||||||
// 2. Trigger a state change
|
|
||||||
relay_chn_run_forward();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
|
|
||||||
// 3. Verify the listener was NOT called
|
|
||||||
TEST_ASSERT_EQUAL(0, listener1_info.call_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
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(&listener2_info);
|
|
||||||
|
|
||||||
// 1. Register two different listeners
|
|
||||||
TEST_ESP_OK(relay_chn_register_listener(test_listener_1));
|
|
||||||
TEST_ESP_OK(relay_chn_register_listener(test_listener_2));
|
|
||||||
|
|
||||||
// 2. Trigger a state change
|
|
||||||
relay_chn_run_forward();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
|
|
||||||
// 3. Verify listener 1 was called correctly
|
|
||||||
TEST_ASSERT_EQUAL(1, listener1_info.call_count);
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, listener1_info.old_state);
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD, listener1_info.new_state);
|
|
||||||
|
|
||||||
// 4. Verify listener 2 was also called correctly
|
|
||||||
TEST_ASSERT_EQUAL(1, listener2_info.call_count);
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, listener2_info.old_state);
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD, listener2_info.new_state);
|
|
||||||
|
|
||||||
// 5. Clean up
|
|
||||||
relay_chn_unregister_listener(test_listener_1);
|
|
||||||
relay_chn_unregister_listener(test_listener_2);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
// 1. Registering a NULL listener should fail
|
|
||||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, relay_chn_register_listener(NULL));
|
|
||||||
|
|
||||||
// 2. Unregistering a NULL listener should not crash
|
|
||||||
relay_chn_unregister_listener(NULL);
|
|
||||||
|
|
||||||
// 3. Registering the same listener twice should be handled gracefully
|
|
||||||
TEST_ESP_OK(relay_chn_register_listener(test_listener_1));
|
|
||||||
TEST_ESP_OK(relay_chn_register_listener(test_listener_1)); // Second call should be a no-op
|
|
||||||
|
|
||||||
// 4. Trigger a state change and verify the listener is only called ONCE
|
|
||||||
relay_chn_run_forward();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(1, listener1_info.call_count);
|
|
||||||
|
|
||||||
// 5. Clean up
|
|
||||||
relay_chn_unregister_listener(test_listener_1);
|
|
||||||
}
|
|
||||||
@@ -23,7 +23,7 @@ void prepare_channel_for_tilt(uint8_t chn_id, int initial_cmd) {
|
|||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms)); // Allow command to process
|
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms)); // Allow command to process
|
||||||
relay_chn_stop(chn_id); // Stop it to set last_run_cmd but return to FREE for next test
|
relay_chn_stop(chn_id); // Stop it to set last_run_cmd but return to FREE for next test
|
||||||
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
|
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state(chn_id));
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FREE, relay_chn_get_state(chn_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TEST_CASE: Test transition from running forward to tilt forward
|
// TEST_CASE: Test transition from running forward to tilt forward
|
||||||
@@ -79,7 +79,7 @@ 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_FREE -> (prepare) -> RELAY_CHN_STATE_FREE -> (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]") {
|
||||||
uint8_t ch = 0;
|
uint8_t ch = 0;
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ TEST_CASE("FREE to Tilt Forward transition with inertia (prepared)", "[relay_chn
|
|||||||
|
|
||||||
// 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_FREE, relay_chn_get_state(ch)); // Ensure we are back to FREE
|
||||||
|
|
||||||
// Issue tilt forward command
|
// Issue tilt forward command
|
||||||
relay_chn_tilt_forward(ch);
|
relay_chn_tilt_forward(ch);
|
||||||
@@ -98,7 +98,7 @@ 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_FREE -> (prepare) -> RELAY_CHN_STATE_FREE -> (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]") {
|
||||||
uint8_t ch = 0;
|
uint8_t ch = 0;
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ TEST_CASE("FREE to Tilt Reverse transition with inertia (prepared)", "[relay_chn
|
|||||||
|
|
||||||
// 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_FREE, relay_chn_get_state(ch)); // Ensure we are back to FREE
|
||||||
|
|
||||||
// Issue tilt reverse command
|
// Issue tilt reverse command
|
||||||
relay_chn_tilt_reverse(ch);
|
relay_chn_tilt_reverse(ch);
|
||||||
@@ -179,7 +179,7 @@ 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_FREE
|
||||||
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;
|
||||||
|
|
||||||
@@ -196,7 +196,7 @@ TEST_CASE("Tilt to Stop transition without immediate inertia for stop", "[relay_
|
|||||||
relay_chn_stop(ch);
|
relay_chn_stop(ch);
|
||||||
// Stop command should apply immediately, setting state to FREE since last state was tilt.
|
// Stop command should apply immediately, setting state to FREE since last state was tilt.
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state(ch));
|
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FREE, relay_chn_get_state(ch));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ### Tilt Broadcast Command (RELAY_CHN_ID_ALL) Tests
|
// ### Tilt Broadcast Command (RELAY_CHN_ID_ALL) Tests
|
||||||
@@ -259,7 +259,7 @@ TEST_CASE("tilt_stop with ID_ALL stops all tilting channels", "[relay_chn][tilt]
|
|||||||
|
|
||||||
// 3. Verify all channels are free
|
// 3. Verify all channels are free
|
||||||
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_FREE, relay_chn_get_state(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,28 +306,28 @@ 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_sensitivity_set 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));
|
TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count));
|
||||||
g_is_component_initialized = true;
|
g_is_component_initialized = true;
|
||||||
|
|
||||||
relay_chn_tilt_set_sensitivity(ch, 0);
|
relay_chn_tilt_sensitivity_set(ch, 0);
|
||||||
TEST_ESP_OK(relay_chn_tilt_get_sensitivity(ch, &val, 1));
|
TEST_ESP_OK(relay_chn_tilt_sensitivity_get(ch, &val, 1));
|
||||||
TEST_ASSERT_EQUAL_UINT8(0, val);
|
TEST_ASSERT_EQUAL_UINT8(0, val);
|
||||||
|
|
||||||
relay_chn_tilt_set_sensitivity(ch, 50);
|
relay_chn_tilt_sensitivity_set(ch, 50);
|
||||||
TEST_ESP_OK(relay_chn_tilt_get_sensitivity(ch, &val, 1));
|
TEST_ESP_OK(relay_chn_tilt_sensitivity_get(ch, &val, 1));
|
||||||
TEST_ASSERT_EQUAL_UINT8(50, val);
|
TEST_ASSERT_EQUAL_UINT8(50, val);
|
||||||
|
|
||||||
relay_chn_tilt_set_sensitivity(ch, 100);
|
relay_chn_tilt_sensitivity_set(ch, 100);
|
||||||
TEST_ESP_OK(relay_chn_tilt_get_sensitivity(ch, &val, 1));
|
TEST_ESP_OK(relay_chn_tilt_sensitivity_get(ch, &val, 1));
|
||||||
TEST_ASSERT_EQUAL_UINT8(100, val);
|
TEST_ASSERT_EQUAL_UINT8(100, val);
|
||||||
|
|
||||||
// Set all channels
|
// Set all channels
|
||||||
relay_chn_tilt_set_sensitivity(RELAY_CHN_ID_ALL, 42);
|
relay_chn_tilt_sensitivity_set(RELAY_CHN_ID_ALL, 42);
|
||||||
uint8_t vals[CONFIG_RELAY_CHN_COUNT] = {0};
|
uint8_t vals[CONFIG_RELAY_CHN_COUNT] = {0};
|
||||||
TEST_ESP_OK(relay_chn_tilt_get_sensitivity(RELAY_CHN_ID_ALL, vals, relay_chn_count));
|
TEST_ESP_OK(relay_chn_tilt_sensitivity_get(RELAY_CHN_ID_ALL, vals, relay_chn_count));
|
||||||
for (int i = 0; i < relay_chn_count; ++i) {
|
for (int i = 0; i < relay_chn_count; ++i) {
|
||||||
TEST_ASSERT_EQUAL_UINT8(42, vals[i]);
|
TEST_ASSERT_EQUAL_UINT8(42, vals[i]);
|
||||||
}
|
}
|
||||||
@@ -1,275 +0,0 @@
|
|||||||
#include "test_common.h"
|
|
||||||
|
|
||||||
|
|
||||||
// ### Tilt Functionality Tests (Conditional)
|
|
||||||
|
|
||||||
// This section will only be compiled if **`CONFIG_RELAY_CHN_ENABLE_TILTING`** is defined as **`1`** in `sdkconfig`.
|
|
||||||
|
|
||||||
#ifndef CONFIG_RELAY_CHN_ENABLE_TILTING
|
|
||||||
#error "This test requires CONFIG_RELAY_CHN_ENABLE_TILTING"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define RELAY_CHN_CMD_FORWARD 1
|
|
||||||
#define RELAY_CHN_CMD_REVERSE 2
|
|
||||||
|
|
||||||
// Helper function to prepare channel for tilt tests
|
|
||||||
void prepare_channel_for_tilt(int initial_cmd) {
|
|
||||||
// Ensure the channel has had a 'last_run_cmd'
|
|
||||||
if (initial_cmd == RELAY_CHN_CMD_FORWARD) {
|
|
||||||
relay_chn_run_forward();
|
|
||||||
} else { // Assuming initial_cmd is RELAY_CHN_CMD_REVERSE
|
|
||||||
relay_chn_run_reverse();
|
|
||||||
}
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms)); // Allow command to process
|
|
||||||
relay_chn_stop(); // Stop it to set last_run_cmd but return to FREE for next test
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
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_for_tilt(RELAY_CHN_CMD_FORWARD);
|
|
||||||
|
|
||||||
// 1. Start in forward direction
|
|
||||||
relay_chn_run_forward();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD, relay_chn_get_state());
|
|
||||||
|
|
||||||
// 2. Issue tilt forward command
|
|
||||||
relay_chn_tilt_forward();
|
|
||||||
// After tilt command, it should immediately stop and then trigger inertia.
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_STOPPED, relay_chn_get_state());
|
|
||||||
|
|
||||||
// Wait for the inertia period (after which the tilt command will be dispatched)
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_TILT_FORWARD, relay_chn_get_state());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
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_for_tilt(RELAY_CHN_CMD_REVERSE);
|
|
||||||
|
|
||||||
// 1. Start in reverse direction
|
|
||||||
relay_chn_run_reverse();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_REVERSE, relay_chn_get_state());
|
|
||||||
|
|
||||||
// 2. Issue tilt reverse command
|
|
||||||
relay_chn_tilt_reverse();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_STOPPED, relay_chn_get_state());
|
|
||||||
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_TILT_REVERSE, relay_chn_get_state());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
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_for_tilt(RELAY_CHN_CMD_FORWARD);
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state()); // Ensure we are back to FREE
|
|
||||||
|
|
||||||
// Issue tilt forward command
|
|
||||||
relay_chn_tilt_forward();
|
|
||||||
// From FREE state, tilt command should still incur the inertia due to the internal timer logic
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_TILT_FORWARD, relay_chn_get_state());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
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_for_tilt(RELAY_CHN_CMD_REVERSE);
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state()); // Ensure we are back to FREE
|
|
||||||
|
|
||||||
// Issue tilt reverse command
|
|
||||||
relay_chn_tilt_reverse();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_TILT_REVERSE, relay_chn_get_state());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
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_for_tilt(RELAY_CHN_CMD_FORWARD);
|
|
||||||
relay_chn_tilt_forward(); // Go to tilt state
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_TILT_FORWARD, relay_chn_get_state());
|
|
||||||
|
|
||||||
// 2. Issue run forward command
|
|
||||||
relay_chn_run_forward();
|
|
||||||
// From Tilt to Run in the same logical name but in the opposite direction, inertia is expected.
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD_PENDING, relay_chn_get_state());
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD, relay_chn_get_state());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
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_for_tilt(RELAY_CHN_CMD_REVERSE);
|
|
||||||
relay_chn_tilt_reverse(); // Go to tilt state
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_TILT_REVERSE, relay_chn_get_state());
|
|
||||||
|
|
||||||
// 2. Issue run reverse command
|
|
||||||
relay_chn_run_reverse();
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_REVERSE_PENDING, relay_chn_get_state());
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_REVERSE, relay_chn_get_state());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
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_for_tilt(RELAY_CHN_CMD_FORWARD);
|
|
||||||
relay_chn_tilt_forward(); // Go to tilt state
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_TILT_FORWARD, relay_chn_get_state());
|
|
||||||
|
|
||||||
// 2. Issue run reverse command (opposite direction)
|
|
||||||
relay_chn_run_reverse();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_REVERSE, relay_chn_get_state());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
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_for_tilt(RELAY_CHN_CMD_FORWARD);
|
|
||||||
relay_chn_tilt_forward(); // Go to tilt state
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_TILT_FORWARD, relay_chn_get_state());
|
|
||||||
|
|
||||||
// 2. Issue stop command
|
|
||||||
relay_chn_stop();
|
|
||||||
// Stop command should apply immediately, setting state to FREE since last state was tilt.
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test relay_chn_tilt_auto() chooses correct tilt direction
|
|
||||||
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_channel_for_tilt(RELAY_CHN_CMD_FORWARD);
|
|
||||||
relay_chn_tilt_auto();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_TILT_FORWARD, relay_chn_get_state());
|
|
||||||
relay_chn_tilt_stop();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
|
|
||||||
// Prepare REVERSE
|
|
||||||
prepare_channel_for_tilt(RELAY_CHN_CMD_REVERSE);
|
|
||||||
relay_chn_tilt_auto();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_TILT_REVERSE, relay_chn_get_state());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test sensitivity set/get
|
|
||||||
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);
|
|
||||||
TEST_ASSERT_EQUAL_UINT8(0, relay_chn_tilt_get_sensitivity());
|
|
||||||
|
|
||||||
relay_chn_tilt_set_sensitivity(50);
|
|
||||||
TEST_ASSERT_EQUAL_UINT8(50, relay_chn_tilt_get_sensitivity());
|
|
||||||
|
|
||||||
relay_chn_tilt_set_sensitivity(100);
|
|
||||||
TEST_ASSERT_EQUAL_UINT8(100, relay_chn_tilt_get_sensitivity());
|
|
||||||
|
|
||||||
relay_chn_tilt_set_sensitivity(42);
|
|
||||||
TEST_ASSERT_EQUAL_UINT8(42, relay_chn_tilt_get_sensitivity());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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_ESP_OK(relay_chn_create(gpio_map, gpio_count));
|
|
||||||
g_is_component_initialized = true;
|
|
||||||
|
|
||||||
prepare_channel_for_tilt(RELAY_CHN_CMD_FORWARD);
|
|
||||||
|
|
||||||
// Tilt forward 3 times
|
|
||||||
for (int i = 0; i < 3; ++i) {
|
|
||||||
relay_chn_tilt_forward();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_TILT_FORWARD, relay_chn_get_state());
|
|
||||||
relay_chn_tilt_stop();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now tilt reverse 3 times (should succeed)
|
|
||||||
for (int i = 0; i < 3; ++i) {
|
|
||||||
relay_chn_tilt_reverse();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
if (i < 3) {
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_TILT_REVERSE, relay_chn_get_state());
|
|
||||||
relay_chn_tilt_stop();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extra reverse tilt should fail (counter exhausted)
|
|
||||||
relay_chn_tilt_reverse();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
// Should not enter TILT_REVERSE, should remain FREE or STOPPED
|
|
||||||
relay_chn_state_t state = relay_chn_get_state();
|
|
||||||
TEST_ASSERT(state != RELAY_CHN_STATE_TILT_REVERSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test run command during TILT state
|
|
||||||
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);
|
|
||||||
relay_chn_tilt_forward();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms));
|
|
||||||
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_TILT_FORWARD, relay_chn_get_state());
|
|
||||||
|
|
||||||
// Issue run reverse while in TILT_FORWARD
|
|
||||||
relay_chn_run_reverse();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(test_delay_margin_ms));
|
|
||||||
// Should transition to REVERSE or REVERSE_PENDING depending on inertia logic
|
|
||||||
relay_chn_state_t state = relay_chn_get_state();
|
|
||||||
TEST_ASSERT(state == RELAY_CHN_STATE_REVERSE || state == RELAY_CHN_STATE_REVERSE_PENDING);
|
|
||||||
}
|
|
||||||
@@ -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,
|
|
||||||
|
@@ -445,6 +445,33 @@ CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y
|
|||||||
# Component config
|
# Component config
|
||||||
#
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Application Level Tracing
|
||||||
|
#
|
||||||
|
CONFIG_APPTRACE_DEST_JTAG=y
|
||||||
|
# CONFIG_APPTRACE_DEST_NONE is not set
|
||||||
|
# CONFIG_APPTRACE_DEST_UART1 is not set
|
||||||
|
# CONFIG_APPTRACE_DEST_UART2 is not set
|
||||||
|
CONFIG_APPTRACE_DEST_UART_NONE=y
|
||||||
|
CONFIG_APPTRACE_UART_TASK_PRIO=1
|
||||||
|
CONFIG_APPTRACE_DEST_TRAX=y
|
||||||
|
CONFIG_APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE=y
|
||||||
|
CONFIG_APPTRACE_ENABLE=y
|
||||||
|
CONFIG_APPTRACE_LOCK_ENABLE=y
|
||||||
|
CONFIG_APPTRACE_ONPANIC_HOST_FLUSH_TMO=-1
|
||||||
|
CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH=0
|
||||||
|
CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX=0
|
||||||
|
|
||||||
|
#
|
||||||
|
# FreeRTOS SystemView Tracing
|
||||||
|
#
|
||||||
|
# CONFIG_APPTRACE_SV_ENABLE is not set
|
||||||
|
# end of FreeRTOS SystemView Tracing
|
||||||
|
|
||||||
|
CONFIG_APPTRACE_GCOV_ENABLE=y
|
||||||
|
CONFIG_APPTRACE_GCOV_DUMP_TASK_STACK_SIZE=2048
|
||||||
|
# end of Application Level Tracing
|
||||||
|
|
||||||
#
|
#
|
||||||
# Driver Configurations
|
# Driver Configurations
|
||||||
#
|
#
|
||||||
@@ -791,8 +818,10 @@ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160
|
|||||||
#
|
#
|
||||||
# Trace memory
|
# Trace memory
|
||||||
#
|
#
|
||||||
|
CONFIG_ESP32_MEMMAP_TRACEMEM=y
|
||||||
|
CONFIG_ESP32_MEMMAP_TRACEMEM_TWOBANKS=y
|
||||||
# CONFIG_ESP32_TRAX is not set
|
# CONFIG_ESP32_TRAX is not set
|
||||||
CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0
|
CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x8000
|
||||||
# end of Trace memory
|
# end of Trace memory
|
||||||
|
|
||||||
# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set
|
# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set
|
||||||
@@ -826,7 +855,7 @@ CONFIG_ESP_INT_WDT_CHECK_CPU1=y
|
|||||||
CONFIG_ESP_TASK_WDT_EN=y
|
CONFIG_ESP_TASK_WDT_EN=y
|
||||||
# CONFIG_ESP_TASK_WDT_INIT is not set
|
# CONFIG_ESP_TASK_WDT_INIT is not set
|
||||||
# CONFIG_ESP_PANIC_HANDLER_IRAM is not set
|
# CONFIG_ESP_PANIC_HANDLER_IRAM is not set
|
||||||
# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set
|
CONFIG_ESP_DEBUG_STUBS_ENABLE=y
|
||||||
CONFIG_ESP_DEBUG_OCDAWARE=y
|
CONFIG_ESP_DEBUG_OCDAWARE=y
|
||||||
# CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set
|
# CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set
|
||||||
CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y
|
CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y
|
||||||
@@ -853,7 +882,7 @@ CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y
|
|||||||
#
|
#
|
||||||
# IPC (Inter-Processor Call)
|
# IPC (Inter-Processor Call)
|
||||||
#
|
#
|
||||||
CONFIG_ESP_IPC_TASK_STACK_SIZE=1024
|
CONFIG_ESP_IPC_TASK_STACK_SIZE=2048
|
||||||
CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y
|
CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y
|
||||||
CONFIG_ESP_IPC_ISR_ENABLE=y
|
CONFIG_ESP_IPC_ISR_ENABLE=y
|
||||||
# end of IPC (Inter-Processor Call)
|
# end of IPC (Inter-Processor Call)
|
||||||
@@ -1261,7 +1290,7 @@ CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
|
|||||||
# Relay Channel Driver Configuration
|
# Relay Channel Driver Configuration
|
||||||
#
|
#
|
||||||
CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS=200
|
CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS=200
|
||||||
CONFIG_RELAY_CHN_COUNT=1
|
CONFIG_RELAY_CHN_COUNT=2
|
||||||
CONFIG_RELAY_CHN_ENABLE_TILTING=y
|
CONFIG_RELAY_CHN_ENABLE_TILTING=y
|
||||||
# end of Relay Channel Driver Configuration
|
# end of Relay Channel Driver Configuration
|
||||||
# end of Component config
|
# end of Component config
|
||||||
@@ -1303,6 +1332,15 @@ CONFIG_STACK_CHECK_NONE=y
|
|||||||
# CONFIG_STACK_CHECK_STRONG is not set
|
# CONFIG_STACK_CHECK_STRONG is not set
|
||||||
# CONFIG_STACK_CHECK_ALL is not set
|
# CONFIG_STACK_CHECK_ALL is not set
|
||||||
# CONFIG_WARN_WRITE_STRINGS is not set
|
# CONFIG_WARN_WRITE_STRINGS is not set
|
||||||
|
CONFIG_ESP32_APPTRACE_DEST_TRAX=y
|
||||||
|
# CONFIG_ESP32_APPTRACE_DEST_NONE is not set
|
||||||
|
CONFIG_ESP32_APPTRACE_ENABLE=y
|
||||||
|
CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y
|
||||||
|
CONFIG_ESP32_APPTRACE_ONPANIC_HOST_FLUSH_TMO=-1
|
||||||
|
CONFIG_ESP32_APPTRACE_POSTMORTEM_FLUSH_TRAX_THRESH=0
|
||||||
|
CONFIG_ESP32_APPTRACE_PENDING_DATA_SIZE_MAX=0
|
||||||
|
# CONFIG_SYSVIEW_ENABLE is not set
|
||||||
|
CONFIG_ESP32_GCOV_ENABLE=y
|
||||||
CONFIG_ADC2_DISABLE_DAC=y
|
CONFIG_ADC2_DISABLE_DAC=y
|
||||||
# CONFIG_MCPWM_ISR_IN_IRAM is not set
|
# CONFIG_MCPWM_ISR_IN_IRAM is not set
|
||||||
# CONFIG_EVENT_LOOP_PROFILING is not set
|
# CONFIG_EVENT_LOOP_PROFILING is not set
|
||||||
@@ -1331,7 +1369,9 @@ CONFIG_ESP32_XTAL_FREQ=40
|
|||||||
CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y
|
CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y
|
||||||
# CONFIG_ESP32_DEFAULT_CPU_FREQ_240 is not set
|
# CONFIG_ESP32_DEFAULT_CPU_FREQ_240 is not set
|
||||||
CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=160
|
CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=160
|
||||||
CONFIG_TRACEMEM_RESERVE_DRAM=0x0
|
CONFIG_MEMMAP_TRACEMEM=y
|
||||||
|
CONFIG_MEMMAP_TRACEMEM_TWOBANKS=y
|
||||||
|
CONFIG_TRACEMEM_RESERVE_DRAM=0x8000
|
||||||
# CONFIG_ESP32_PANIC_PRINT_HALT is not set
|
# CONFIG_ESP32_PANIC_PRINT_HALT is not set
|
||||||
CONFIG_ESP32_PANIC_PRINT_REBOOT=y
|
CONFIG_ESP32_PANIC_PRINT_REBOOT=y
|
||||||
# CONFIG_ESP32_PANIC_SILENT_REBOOT is not set
|
# CONFIG_ESP32_PANIC_SILENT_REBOOT is not set
|
||||||
@@ -1350,7 +1390,7 @@ CONFIG_INT_WDT_TIMEOUT_MS=300
|
|||||||
CONFIG_INT_WDT_CHECK_CPU1=y
|
CONFIG_INT_WDT_CHECK_CPU1=y
|
||||||
# CONFIG_TASK_WDT is not set
|
# CONFIG_TASK_WDT is not set
|
||||||
# CONFIG_ESP_TASK_WDT is not set
|
# CONFIG_ESP_TASK_WDT is not set
|
||||||
# CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set
|
CONFIG_ESP32_DEBUG_STUBS_ENABLE=y
|
||||||
CONFIG_ESP32_DEBUG_OCDAWARE=y
|
CONFIG_ESP32_DEBUG_OCDAWARE=y
|
||||||
CONFIG_BROWNOUT_DET=y
|
CONFIG_BROWNOUT_DET=y
|
||||||
CONFIG_ESP32_BROWNOUT_DET=y
|
CONFIG_ESP32_BROWNOUT_DET=y
|
||||||
@@ -1373,7 +1413,7 @@ CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y
|
|||||||
CONFIG_BROWNOUT_DET_LVL=0
|
CONFIG_BROWNOUT_DET_LVL=0
|
||||||
CONFIG_ESP32_BROWNOUT_DET_LVL=0
|
CONFIG_ESP32_BROWNOUT_DET_LVL=0
|
||||||
# CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set
|
# CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set
|
||||||
CONFIG_IPC_TASK_STACK_SIZE=1024
|
CONFIG_IPC_TASK_STACK_SIZE=2048
|
||||||
CONFIG_TIMER_TASK_STACK_SIZE=3584
|
CONFIG_TIMER_TASK_STACK_SIZE=3584
|
||||||
CONFIG_TIMER_TASK_PRIORITY=1
|
CONFIG_TIMER_TASK_PRIORITY=1
|
||||||
CONFIG_TIMER_TASK_STACK_DEPTH=2048
|
CONFIG_TIMER_TASK_STACK_DEPTH=2048
|
||||||
|
|||||||
@@ -6,3 +6,12 @@ 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
|
||||||
|
|
||||||
|
# App Trace config
|
||||||
|
CONFIG_APPTRACE_DEST_JTAG=y
|
||||||
|
CONFIG_APPTRACE_ENABLE=y
|
||||||
|
CONFIG_APPTRACE_LOCK_ENABLE=y
|
||||||
|
CONFIG_APPTRACE_ONPANIC_HOST_FLUSH_TMO=-1
|
||||||
|
CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH=0
|
||||||
|
CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX=0
|
||||||
|
CONFIG_APPTRACE_GCOV_ENABLE=y
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
# Disable task WDT for tests
|
|
||||||
CONFIG_ESP_TASK_WDT_INIT=n
|
|
||||||
|
|
||||||
# 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
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#
|
#
|
||||||
# Automatically generated file. DO NOT EDIT.
|
# Automatically generated file. DO NOT EDIT.
|
||||||
# Espressif IoT Development Framework (ESP-IDF) 5.4.0 Project Configuration
|
# Espressif IoT Development Framework (ESP-IDF) 5.4.2 Project Configuration
|
||||||
#
|
#
|
||||||
CONFIG_SOC_BROWNOUT_RESET_SUPPORTED="Not determined"
|
CONFIG_SOC_BROWNOUT_RESET_SUPPORTED="Not determined"
|
||||||
CONFIG_SOC_TWAI_BRP_DIV_SUPPORTED="Not determined"
|
CONFIG_SOC_TWAI_BRP_DIV_SUPPORTED="Not determined"
|
||||||
@@ -98,6 +98,7 @@ CONFIG_SOC_I2C_FIFO_LEN=32
|
|||||||
CONFIG_SOC_I2C_CMD_REG_NUM=16
|
CONFIG_SOC_I2C_CMD_REG_NUM=16
|
||||||
CONFIG_SOC_I2C_SUPPORT_SLAVE=y
|
CONFIG_SOC_I2C_SUPPORT_SLAVE=y
|
||||||
CONFIG_SOC_I2C_SUPPORT_APB=y
|
CONFIG_SOC_I2C_SUPPORT_APB=y
|
||||||
|
CONFIG_SOC_I2C_SUPPORT_10BIT_ADDR=y
|
||||||
CONFIG_SOC_I2C_STOP_INDEPENDENT=y
|
CONFIG_SOC_I2C_STOP_INDEPENDENT=y
|
||||||
CONFIG_SOC_I2S_NUM=2
|
CONFIG_SOC_I2S_NUM=2
|
||||||
CONFIG_SOC_I2S_HW_VERSION_1=y
|
CONFIG_SOC_I2S_HW_VERSION_1=y
|
||||||
@@ -175,6 +176,8 @@ CONFIG_SOC_TIMER_GROUP_TIMERS_PER_GROUP=2
|
|||||||
CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64
|
CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64
|
||||||
CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4
|
CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4
|
||||||
CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y
|
CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y
|
||||||
|
CONFIG_SOC_LP_TIMER_BIT_WIDTH_LO=32
|
||||||
|
CONFIG_SOC_LP_TIMER_BIT_WIDTH_HI=16
|
||||||
CONFIG_SOC_TOUCH_SENSOR_VERSION=1
|
CONFIG_SOC_TOUCH_SENSOR_VERSION=1
|
||||||
CONFIG_SOC_TOUCH_SENSOR_NUM=10
|
CONFIG_SOC_TOUCH_SENSOR_NUM=10
|
||||||
CONFIG_SOC_TOUCH_SAMPLE_CFG_NUM=1
|
CONFIG_SOC_TOUCH_SAMPLE_CFG_NUM=1
|
||||||
@@ -244,7 +247,7 @@ CONFIG_IDF_TOOLCHAIN_GCC=y
|
|||||||
CONFIG_IDF_TARGET_ARCH_XTENSA=y
|
CONFIG_IDF_TARGET_ARCH_XTENSA=y
|
||||||
CONFIG_IDF_TARGET_ARCH="xtensa"
|
CONFIG_IDF_TARGET_ARCH="xtensa"
|
||||||
CONFIG_IDF_TARGET="esp32"
|
CONFIG_IDF_TARGET="esp32"
|
||||||
CONFIG_IDF_INIT_VERSION="$IDF_INIT_VERSION"
|
CONFIG_IDF_INIT_VERSION="5.4.2"
|
||||||
CONFIG_IDF_TARGET_ESP32=y
|
CONFIG_IDF_TARGET_ESP32=y
|
||||||
CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000
|
CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000
|
||||||
|
|
||||||
@@ -285,10 +288,10 @@ CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
|
|||||||
# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set
|
# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set
|
||||||
# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set
|
# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set
|
||||||
# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set
|
# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set
|
||||||
# CONFIG_BOOTLOADER_LOG_LEVEL_INFO is not set
|
CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y
|
||||||
CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG=y
|
# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set
|
||||||
# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set
|
# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set
|
||||||
CONFIG_BOOTLOADER_LOG_LEVEL=4
|
CONFIG_BOOTLOADER_LOG_LEVEL=3
|
||||||
|
|
||||||
#
|
#
|
||||||
# Format
|
# Format
|
||||||
@@ -399,7 +402,7 @@ CONFIG_PARTITION_TABLE_SINGLE_APP=y
|
|||||||
# CONFIG_PARTITION_TABLE_CUSTOM is not set
|
# CONFIG_PARTITION_TABLE_CUSTOM is not set
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv"
|
CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv"
|
||||||
CONFIG_PARTITION_TABLE_OFFSET=0x9000
|
CONFIG_PARTITION_TABLE_OFFSET=0x8000
|
||||||
CONFIG_PARTITION_TABLE_MD5=y
|
CONFIG_PARTITION_TABLE_MD5=y
|
||||||
# end of Partition Table
|
# end of Partition Table
|
||||||
|
|
||||||
@@ -442,6 +445,18 @@ CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y
|
|||||||
# Component config
|
# Component config
|
||||||
#
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Application Level Tracing
|
||||||
|
#
|
||||||
|
# CONFIG_APPTRACE_DEST_JTAG is not set
|
||||||
|
CONFIG_APPTRACE_DEST_NONE=y
|
||||||
|
# CONFIG_APPTRACE_DEST_UART1 is not set
|
||||||
|
# CONFIG_APPTRACE_DEST_UART2 is not set
|
||||||
|
CONFIG_APPTRACE_DEST_UART_NONE=y
|
||||||
|
CONFIG_APPTRACE_UART_TASK_PRIO=1
|
||||||
|
CONFIG_APPTRACE_LOCK_ENABLE=y
|
||||||
|
# end of Application Level Tracing
|
||||||
|
|
||||||
#
|
#
|
||||||
# Driver Configurations
|
# Driver Configurations
|
||||||
#
|
#
|
||||||
@@ -462,6 +477,7 @@ CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y
|
|||||||
#
|
#
|
||||||
CONFIG_ADC_DISABLE_DAC=y
|
CONFIG_ADC_DISABLE_DAC=y
|
||||||
# CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set
|
# CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set
|
||||||
|
# CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# Legacy ADC Calibration Configuration
|
# Legacy ADC Calibration Configuration
|
||||||
@@ -477,42 +493,55 @@ CONFIG_ADC_CAL_LUT_ENABLE=y
|
|||||||
# Legacy DAC Driver Configurations
|
# Legacy DAC Driver Configurations
|
||||||
#
|
#
|
||||||
# CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set
|
# CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set
|
||||||
|
# CONFIG_DAC_SKIP_LEGACY_CONFLICT_CHECK is not set
|
||||||
# end of Legacy DAC Driver Configurations
|
# end of Legacy DAC Driver Configurations
|
||||||
|
|
||||||
#
|
#
|
||||||
# Legacy MCPWM Driver Configurations
|
# Legacy MCPWM Driver Configurations
|
||||||
#
|
#
|
||||||
# CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set
|
# CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set
|
||||||
|
# CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK is not set
|
||||||
# end of Legacy MCPWM Driver Configurations
|
# end of Legacy MCPWM Driver Configurations
|
||||||
|
|
||||||
#
|
#
|
||||||
# Legacy Timer Group Driver Configurations
|
# Legacy Timer Group Driver Configurations
|
||||||
#
|
#
|
||||||
# CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set
|
# CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set
|
||||||
|
# CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK is not set
|
||||||
# end of Legacy Timer Group Driver Configurations
|
# end of Legacy Timer Group Driver Configurations
|
||||||
|
|
||||||
#
|
#
|
||||||
# Legacy RMT Driver Configurations
|
# Legacy RMT Driver Configurations
|
||||||
#
|
#
|
||||||
# CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set
|
# CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set
|
||||||
|
# CONFIG_RMT_SKIP_LEGACY_CONFLICT_CHECK is not set
|
||||||
# end of Legacy RMT Driver Configurations
|
# end of Legacy RMT Driver Configurations
|
||||||
|
|
||||||
#
|
#
|
||||||
# Legacy I2S Driver Configurations
|
# Legacy I2S Driver Configurations
|
||||||
#
|
#
|
||||||
# CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set
|
# CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set
|
||||||
|
# CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set
|
||||||
# end of Legacy I2S Driver Configurations
|
# end of Legacy I2S Driver Configurations
|
||||||
|
|
||||||
|
#
|
||||||
|
# Legacy I2C Driver Configurations
|
||||||
|
#
|
||||||
|
# CONFIG_I2C_SKIP_LEGACY_CONFLICT_CHECK is not set
|
||||||
|
# end of Legacy I2C Driver Configurations
|
||||||
|
|
||||||
#
|
#
|
||||||
# Legacy PCNT Driver Configurations
|
# Legacy PCNT Driver Configurations
|
||||||
#
|
#
|
||||||
# CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set
|
# CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set
|
||||||
|
# CONFIG_PCNT_SKIP_LEGACY_CONFLICT_CHECK is not set
|
||||||
# end of Legacy PCNT Driver Configurations
|
# end of Legacy PCNT Driver Configurations
|
||||||
|
|
||||||
#
|
#
|
||||||
# Legacy SDM Driver Configurations
|
# Legacy SDM Driver Configurations
|
||||||
#
|
#
|
||||||
# CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set
|
# CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set
|
||||||
|
# CONFIG_SDM_SKIP_LEGACY_CONFLICT_CHECK is not set
|
||||||
# end of Legacy SDM Driver Configurations
|
# end of Legacy SDM Driver Configurations
|
||||||
# end of Driver Configurations
|
# end of Driver Configurations
|
||||||
|
|
||||||
@@ -555,6 +584,7 @@ CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y
|
|||||||
CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y
|
CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y
|
||||||
# CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set
|
# CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set
|
||||||
# CONFIG_GPTIMER_ISR_IRAM_SAFE is not set
|
# CONFIG_GPTIMER_ISR_IRAM_SAFE is not set
|
||||||
|
CONFIG_GPTIMER_OBJ_CACHE_SAFE=y
|
||||||
# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set
|
# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set
|
||||||
# end of ESP-Driver:GPTimer Configurations
|
# end of ESP-Driver:GPTimer Configurations
|
||||||
|
|
||||||
@@ -706,7 +736,7 @@ CONFIG_RTC_CLK_CAL_CYCLES=1024
|
|||||||
#
|
#
|
||||||
# Peripheral Control
|
# Peripheral Control
|
||||||
#
|
#
|
||||||
CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y
|
# CONFIG_PERIPH_CTRL_FUNC_IN_IRAM is not set
|
||||||
# end of Peripheral Control
|
# end of Peripheral Control
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -936,7 +966,6 @@ CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y
|
|||||||
CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2
|
CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2
|
||||||
CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y
|
CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y
|
||||||
CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y
|
CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y
|
||||||
# CONFIG_HAL_ECDSA_GEN_SIG_CM is not set
|
|
||||||
# end of Hardware Abstraction Layer (HAL) and Low Level (LL)
|
# end of Hardware Abstraction Layer (HAL) and Low Level (LL)
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -1045,6 +1074,7 @@ CONFIG_MBEDTLS_HAVE_TIME=y
|
|||||||
# CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set
|
# CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set
|
||||||
# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set
|
# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set
|
||||||
CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y
|
CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y
|
||||||
|
CONFIG_MBEDTLS_SHA1_C=y
|
||||||
CONFIG_MBEDTLS_SHA512_C=y
|
CONFIG_MBEDTLS_SHA512_C=y
|
||||||
# CONFIG_MBEDTLS_SHA3_C is not set
|
# CONFIG_MBEDTLS_SHA3_C is not set
|
||||||
CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y
|
CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y
|
||||||
@@ -1125,6 +1155,7 @@ CONFIG_MBEDTLS_ECP_NIST_OPTIM=y
|
|||||||
# CONFIG_MBEDTLS_HKDF_C is not set
|
# CONFIG_MBEDTLS_HKDF_C is not set
|
||||||
# CONFIG_MBEDTLS_THREADING_C is not set
|
# CONFIG_MBEDTLS_THREADING_C is not set
|
||||||
CONFIG_MBEDTLS_ERROR_STRINGS=y
|
CONFIG_MBEDTLS_ERROR_STRINGS=y
|
||||||
|
# CONFIG_MBEDTLS_ALLOW_WEAK_CERTIFICATE_VERIFICATION is not set
|
||||||
# end of mbedTLS
|
# end of mbedTLS
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -1184,6 +1215,7 @@ CONFIG_SPI_FLASH_BROWNOUT_RESET=y
|
|||||||
#
|
#
|
||||||
CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50
|
CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50
|
||||||
# CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set
|
# CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set
|
||||||
|
# CONFIG_SPI_FLASH_FORCE_ENABLE_C6_H2_SUSPEND is not set
|
||||||
# end of Optional and Experimental Features (READ DOCS FIRST)
|
# end of Optional and Experimental Features (READ DOCS FIRST)
|
||||||
# end of Main Flash configuration
|
# end of Main Flash configuration
|
||||||
|
|
||||||
@@ -1257,10 +1289,10 @@ CONFIG_RELAY_CHN_ENABLE_TILTING=y
|
|||||||
# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set
|
# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set
|
||||||
# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set
|
# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set
|
||||||
# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set
|
# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set
|
||||||
# CONFIG_LOG_BOOTLOADER_LEVEL_INFO is not set
|
CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y
|
||||||
CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG=y
|
# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set
|
||||||
# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set
|
# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set
|
||||||
CONFIG_LOG_BOOTLOADER_LEVEL=4
|
CONFIG_LOG_BOOTLOADER_LEVEL=3
|
||||||
# CONFIG_APP_ROLLBACK_ENABLE is not set
|
# CONFIG_APP_ROLLBACK_ENABLE is not set
|
||||||
# CONFIG_FLASH_ENCRYPTION_ENABLED is not set
|
# CONFIG_FLASH_ENCRYPTION_ENABLED is not set
|
||||||
# CONFIG_FLASHMODE_QIO is not set
|
# CONFIG_FLASHMODE_QIO is not set
|
||||||
@@ -1283,6 +1315,9 @@ CONFIG_STACK_CHECK_NONE=y
|
|||||||
# CONFIG_STACK_CHECK_STRONG is not set
|
# CONFIG_STACK_CHECK_STRONG is not set
|
||||||
# CONFIG_STACK_CHECK_ALL is not set
|
# CONFIG_STACK_CHECK_ALL is not set
|
||||||
# CONFIG_WARN_WRITE_STRINGS is not set
|
# CONFIG_WARN_WRITE_STRINGS is not set
|
||||||
|
# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set
|
||||||
|
CONFIG_ESP32_APPTRACE_DEST_NONE=y
|
||||||
|
CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y
|
||||||
CONFIG_ADC2_DISABLE_DAC=y
|
CONFIG_ADC2_DISABLE_DAC=y
|
||||||
# CONFIG_MCPWM_ISR_IN_IRAM is not set
|
# CONFIG_MCPWM_ISR_IN_IRAM is not set
|
||||||
# CONFIG_EVENT_LOOP_PROFILING is not set
|
# CONFIG_EVENT_LOOP_PROFILING is not set
|
||||||
|
|||||||
Reference in New Issue
Block a user