diff --git a/CMakeLists.txt b/CMakeLists.txt index b301f47..e5b0c68 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,21 @@ -idf_component_register(SRCS "src/relay_chn.c" - INCLUDE_DIRS include - REQUIRES driver - PRIV_REQUIRES esp_timer esp_event) +set(include_dirs "include") +set(priv_include_dirs "private_include") + +set(srcs "src/relay_chn_core.c" + "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) diff --git a/README.md b/README.md index aba6d7b..0597737 100644 --- a/README.md +++ b/README.md @@ -43,11 +43,28 @@ dependencies: ## 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 ```c // Define GPIO pins for relay channels -const gpio_num_t gpio_map[] = {GPIO_NUM_4, GPIO_NUM_5}; // One channel example +const uint8_t gpio_map[] = {4, 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]); // Create and initialize relay channels @@ -59,53 +76,138 @@ if (ret != ESP_OK) { ### 2. Control relay channels +For single mode: + ```c -// Run channel 0 forward +// Run the channel 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); +// Run all channels forward +relay_chn_run_forward(RELAY_CHN_ID_ALL); -// Run channel 0 reverse -relay_chn_run_reverse(0); +// Run channel #1 reverse +relay_chn_run_reverse(1); +// Run all channels reverse +relay_chn_run_reverse(RELAY_CHN_ID_ALL); -// Stop channel 0 -relay_chn_stop(0); +// Stop channel #1 +relay_chn_stop(1); +// 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); +// Flip direction of all channels +relay_chn_flip_direction(RELAY_CHN_ID_ALL); ``` ### 3. Monitor channel state +For single mode: + ```c // Get channel state -relay_chn_state_t state = relay_chn_get_state(0); -char *state_str = relay_chn_get_state_str(0); +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); +// Get the string representation of the state of the channel #0 +char *state_str = relay_chn_get_state_str(0); + +// Get channel #0 direction relay_chn_direction_t direction = relay_chn_get_direction(0); + +/* The listener is same for multi mode */ ``` ### 4. Tilting Interface (if enabled) +For single mode: + ```c // Assuming CONFIG_RELAY_CHN_ENABLE_TILTING is enabled -// Start tilting automatically (channel 0) +// Start tilting automatically +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(RELAY_CHN_ID_ALL); // on all channels -// Tilt forward (channel 0) -relay_chn_tilt_forward(0); +// Tilt forward on channel #1 +relay_chn_tilt_forward(1); +relay_chn_tilt_forward(RELAY_CHN_ID_ALL); -// Tilt reverse (channel 0) -relay_chn_tilt_reverse(0); +// Tilt reverse on channel #2 +relay_chn_tilt_reverse(2); +relay_chn_tilt_reverse(RELAY_CHN_ID_ALL); -// Stop tilting (channel 0) +// Stop tilting on channel #0 relay_chn_tilt_stop(0); +relay_chn_tilt_stop(RELAY_CHN_ID_ALL); -// Set tilting sensitivity (channel 0, sensitivity as percentage) +// Set tilting sensitivity (sensitivity as percentage) for channel #0 relay_chn_tilt_sensitivity_set(0, 90); +relay_chn_tilt_sensitivity_set(RELAY_CHN_ID_ALL, 90); -// Get tilting sensitivity (channel 0, sensitivty as percentage) -uint8_t sensitivity = relay_chn_tilt_sensitivity_get(0); +// Get tilting sensitivity (sensitivty as percentage) +uint8_t sensitivity; +relay_chn_tilt_get_sensitivity(0, &sensitivity, sizeof(sensitivity)); ``` ## License diff --git a/include/relay_chn.h b/include/relay_chn.h index 5d7f8a0..9912860 100644 --- a/include/relay_chn.h +++ b/include/relay_chn.h @@ -1,16 +1,8 @@ -#ifndef RELAY_CHN_H -#define RELAY_CHN_H -/** - * @file relay_chn.h - * - * @author - * Ismail Sahillioglu +/* + * SPDX-FileCopyrightText: 2025 Kozmotronik Tech + * + * SPDX-License-Identifier: MIT * - * @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. * 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. @@ -22,66 +14,17 @@ * reliability and prevent conflict operations. Also, the esp timer is used to manage the direction change inertia. */ +#pragma once + #include "esp_err.h" -#include "driver/gpio.h" -#include +#include "relay_chn_defs.h" +#include "relay_chn_types.h" +#include "relay_chn_adapter.h" #ifdef __cplusplus extern "C" { #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. * @@ -95,7 +38,7 @@ typedef void (*relay_chn_state_listener_t)(uint8_t chn_id, relay_chn_state_t old * - ESP_ERR_INVALID_ARG: Invalid argument * - ESP_FAIL: General failure */ -esp_err_t relay_chn_create(const gpio_num_t* gpio_map, uint8_t gpio_count); +esp_err_t relay_chn_create(const uint8_t* gpio_map, uint8_t gpio_count); /** * @brief Destroy the relay channels and free resources. @@ -124,6 +67,7 @@ esp_err_t relay_chn_register_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. * @@ -150,14 +94,6 @@ relay_chn_state_t relay_chn_get_state(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. * @@ -191,8 +127,7 @@ void relay_chn_stop(uint8_t chn_id); * @brief Flips the direction of the specified relay channel. * * This function toggles the direction of the relay channel identified by the - * given channel ID. It is typically used to change the state of the relay - * from its current direction to the opposite direction. + * given channel ID. * * @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. @@ -217,9 +152,9 @@ relay_chn_direction_t relay_chn_get_direction(uint8_t chn_id); /** * @brief Enables automatic tilting for the specified 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 some internal sensing mechanism (not detailed here). - * Requires appropriate hardware support and configuration. + * 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 * * @param chn_id The ID of the relay channel to enable automatic tilting. */ @@ -228,8 +163,7 @@ void relay_chn_tilt_auto(uint8_t chn_id); /** * @brief Tilts the specified relay channel forward. * - * This function initiates a forward tilting action for the specified relay channel. This is a manual tilting - * operation, unlike `relay_chn_tilt_auto()`. + * This function initiates a forward tilting action for the specified relay channel. * * @param chn_id The ID of the relay channel to tilt forward. */ @@ -238,8 +172,7 @@ void relay_chn_tilt_forward(uint8_t chn_id); /** * @brief Tilts the specified relay channel reverse. * - * This function initiates a reverse tilting action for the specified relay channel. This is a manual tilting - * operation, unlike `relay_chn_tilt_auto()`. + * This function initiates a reverse tilting action for the specified relay channel. * * @param chn_id The ID of the relay channel to tilt reverse. */ @@ -263,7 +196,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 sensitivity The sensitivity in percentage: 0 - 100%. */ -void relay_chn_tilt_sensitivity_set(uint8_t chn_id, uint8_t sensitivity); +void relay_chn_tilt_set_sensitivity(uint8_t chn_id, uint8_t sensitivity); /** * @brief Gets the tilting sensitivity for the specified relay channel. @@ -278,14 +211,127 @@ void relay_chn_tilt_sensitivity_set(uint8_t chn_id, uint8_t sensitivity); * - ESP_OK: Success * - ESP_ERR_INVALID_ARG: Invalid argument */ -esp_err_t relay_chn_tilt_sensitivity_get(uint8_t chn_id, uint8_t *sensitivity, size_t length); +esp_err_t relay_chn_tilt_get_sensitivity(uint8_t chn_id, uint8_t *sensitivity, size_t length); #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 } -#endif - -/// @} - -#endif // RELAY_CHN_H \ No newline at end of file +#endif \ No newline at end of file