103 lines
3.6 KiB
C
103 lines
3.6 KiB
C
#include "relay_ctrl.h"
|
|
|
|
#include "esp_check.h"
|
|
#include "esp_log.h"
|
|
|
|
static const char *TAG = "relay_ctrl";
|
|
|
|
typedef struct {
|
|
bool inited;
|
|
bool active_high;
|
|
gpio_num_t pins[RELAY_CTRL_ID_MAX];
|
|
bool states[RELAY_CTRL_ID_MAX];
|
|
} relay_ctx_t;
|
|
|
|
static relay_ctx_t s_ctx;
|
|
|
|
static inline int relay_level_from_state(bool on)
|
|
{
|
|
return (on == s_ctx.active_high) ? 1 : 0;
|
|
}
|
|
|
|
static esp_err_t relay_validate_id(relay_ctrl_id_t relay_id)
|
|
{
|
|
ESP_RETURN_ON_FALSE(relay_id >= RELAY_CTRL_ID_1 && relay_id < RELAY_CTRL_ID_MAX,
|
|
ESP_ERR_INVALID_ARG, TAG, "invalid relay id");
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_err_t relay_ctrl_init(gpio_num_t relay1_gpio, gpio_num_t relay2_gpio, bool active_high)
|
|
{
|
|
ESP_RETURN_ON_FALSE(GPIO_IS_VALID_OUTPUT_GPIO(relay1_gpio), ESP_ERR_INVALID_ARG, TAG, "relay1 gpio invalid");
|
|
ESP_RETURN_ON_FALSE(GPIO_IS_VALID_OUTPUT_GPIO(relay2_gpio), ESP_ERR_INVALID_ARG, TAG, "relay2 gpio invalid");
|
|
|
|
s_ctx.active_high = active_high;
|
|
s_ctx.pins[RELAY_CTRL_ID_1] = relay1_gpio;
|
|
s_ctx.pins[RELAY_CTRL_ID_2] = relay2_gpio;
|
|
|
|
const gpio_config_t io_cfg = {
|
|
.pin_bit_mask = (1ULL << relay1_gpio) | (1ULL << relay2_gpio),
|
|
.mode = GPIO_MODE_OUTPUT,
|
|
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
|
.pull_up_en = GPIO_PULLUP_DISABLE,
|
|
.intr_type = GPIO_INTR_DISABLE,
|
|
};
|
|
ESP_RETURN_ON_ERROR(gpio_config(&io_cfg), TAG, "relay gpio config failed");
|
|
|
|
// 默认上电全部断开
|
|
s_ctx.states[RELAY_CTRL_ID_1] = false;
|
|
s_ctx.states[RELAY_CTRL_ID_2] = false;
|
|
ESP_RETURN_ON_ERROR(gpio_set_level(relay1_gpio, relay_level_from_state(false)), TAG, "relay1 set init level failed");
|
|
ESP_RETURN_ON_ERROR(gpio_set_level(relay2_gpio, relay_level_from_state(false)), TAG, "relay2 set init level failed");
|
|
|
|
s_ctx.inited = true;
|
|
ESP_LOGI(TAG, "继电器初始化完成: relay1=GPIO%d relay2=GPIO%d active_high=%d",
|
|
relay1_gpio,
|
|
relay2_gpio,
|
|
active_high);
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_err_t relay_ctrl_set(relay_ctrl_id_t relay_id, bool on)
|
|
{
|
|
ESP_RETURN_ON_FALSE(s_ctx.inited, ESP_ERR_INVALID_STATE, TAG, "relay not initialized");
|
|
ESP_RETURN_ON_ERROR(relay_validate_id(relay_id), TAG, "invalid relay id");
|
|
|
|
ESP_RETURN_ON_ERROR(gpio_set_level(s_ctx.pins[relay_id], relay_level_from_state(on)),
|
|
TAG,
|
|
"relay set level failed");
|
|
s_ctx.states[relay_id] = on;
|
|
ESP_LOGI(TAG, "继电器%d -> %s (GPIO%d level=%d)",
|
|
relay_id + 1,
|
|
on ? "ON" : "OFF",
|
|
s_ctx.pins[relay_id],
|
|
relay_level_from_state(on));
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_err_t relay_ctrl_toggle(relay_ctrl_id_t relay_id)
|
|
{
|
|
ESP_RETURN_ON_FALSE(s_ctx.inited, ESP_ERR_INVALID_STATE, TAG, "relay not initialized");
|
|
ESP_RETURN_ON_ERROR(relay_validate_id(relay_id), TAG, "invalid relay id");
|
|
|
|
return relay_ctrl_set(relay_id, !s_ctx.states[relay_id]);
|
|
}
|
|
|
|
esp_err_t relay_ctrl_get(relay_ctrl_id_t relay_id, bool *on_out)
|
|
{
|
|
ESP_RETURN_ON_FALSE(s_ctx.inited, ESP_ERR_INVALID_STATE, TAG, "relay not initialized");
|
|
ESP_RETURN_ON_FALSE(on_out != NULL, ESP_ERR_INVALID_ARG, TAG, "on_out is null");
|
|
ESP_RETURN_ON_ERROR(relay_validate_id(relay_id), TAG, "invalid relay id");
|
|
|
|
*on_out = s_ctx.states[relay_id];
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_err_t relay_ctrl_set_all(bool relay1_on, bool relay2_on)
|
|
{
|
|
ESP_RETURN_ON_FALSE(s_ctx.inited, ESP_ERR_INVALID_STATE, TAG, "relay not initialized");
|
|
ESP_RETURN_ON_ERROR(relay_ctrl_set(RELAY_CTRL_ID_1, relay1_on), TAG, "set relay1 failed");
|
|
ESP_RETURN_ON_ERROR(relay_ctrl_set(RELAY_CTRL_ID_2, relay2_on), TAG, "set relay2 failed");
|
|
return ESP_OK;
|
|
}
|