Files
zTC1/TC1/user_gpio.c
2025-03-21 12:45:21 +08:00

358 lines
11 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "http_server/web_log.h"
#include "main.h"
#include "user_gpio.h"
#include "user_wifi.h"
#include "mqtt_server/user_mqtt_client.h"
mico_gpio_t relay[Relay_NUM] = {Relay_0, Relay_1, Relay_2, Relay_3, Relay_4, Relay_5};
char socket_status[32] = {0};
char short_click_config[32] = {0};
char long_click_config[32] = {0};
void UserLedSet(char x) {
if (x == -1)
MicoGpioOutputTrigger(Led);
else if (x)
MicoGpioOutputHigh(Led);
else
MicoGpioOutputLow(Led);
}
bool RelayOut(void) {
int i;
for (i = 0; i < SOCKET_NUM; i++) {
if (user_config->socket_status[i] != 0) {
return true;
}
}
return false;
}
const char *get_func_name(char func_code) {
static char buffer[32];
switch (func_code) {
case SWITCH_ALL_SOCKETS:
return "Toggle All Sockets";
case SWITCH_SOCKET_1:
case SWITCH_SOCKET_2:
case SWITCH_SOCKET_3:
case SWITCH_SOCKET_4:
case SWITCH_SOCKET_5:
case SWITCH_SOCKET_6:
sprintf(buffer, "Toggle Socket %d %s", func_code - 1,
user_config->socket_names[func_code - 1]);
return buffer;
case SWITCH_LED_ENABLE:
return "Toggle LED";
case REBOOT_SYSTEM:
return "Reboot";
case CONFIG_WIFI:
return "WiFi Config";
case RESET_SYSTEM:
return "Factory Reset";
case -1:
case NO_FUNCTION:
return "Unassigned";
default:
return "Unknown";
}
}
/// 针对电源按钮的点击事件
/// \param index 判断短按(连击)时,代表连击次数,判断长按时代表长按秒数
/// \param short_func 功能码 在user_gpio.h中定义了
/// \param long_func 功能码 在user_gpio.h中定义了
void set_key_map(int index, char short_func, char long_func) {
user_config->user[index] = ((long_func & 0x0F) << 4) | (short_func & 0x0F);
}
char get_short_func(char val) {
char func = val & 0x0F;
return (func == NO_FUNCTION) ? -1 : func; // -1 表示未配置
}
char get_long_func(char val) {
char func = (val >> 4) & 0x0F;
return (func == NO_FUNCTION) ? -1 : func; // -1 表示未配置
}
char *GetSocketStatus() {
sprintf(socket_status, "%d,%d,%d,%d,%d,%d",
user_config->socket_status[0],
user_config->socket_status[1],
user_config->socket_status[2],
user_config->socket_status[3],
user_config->socket_status[4],
user_config->socket_status[5]);
return socket_status;
}
char *GetShortClickConfig() {
sprintf(short_click_config, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
get_short_func(user_config->user[1]),
get_short_func(user_config->user[2]),
get_short_func(user_config->user[3]),
get_short_func(user_config->user[4]),
get_short_func(user_config->user[5]),
get_short_func(user_config->user[6]),
get_short_func(user_config->user[7]),
get_short_func(user_config->user[8]),
get_short_func(user_config->user[9]),
get_short_func(user_config->user[10]));
return short_click_config;
}
void SetSocketStatus(char *socket_status) {
sscanf(socket_status, "%d,%d,%d,%d,%d,%d,",
(int *) &user_config->socket_status[0],
(int *) &user_config->socket_status[1],
(int *) &user_config->socket_status[2],
(int *) &user_config->socket_status[3],
(int *) &user_config->socket_status[4],
(int *) &user_config->socket_status[5]);
int i = 0;
for (i = 0; i < SOCKET_NUM; i++) {
UserRelaySet(i, user_config->socket_status[i]);
UserMqttSendSocketState(i);
}
UserMqttSendTotalSocketState();
mico_system_context_update(sys_config);
}
/*UserRelaySet
* 设置继电器开关
* i:编号 0-5
* on:开关 0:关 1:开 -1:切换
*/
void UserRelaySet(unsigned char i, char on) {
if (i < 0 || i >= SOCKET_NUM) return;
if (on == Relay_ON) {
MicoGpioOutputHigh(relay[i]);
} else if (on == Relay_OFF) {
MicoGpioOutputLow(relay[i]);
} else if (on == Relay_TOGGLE) {
if (user_config->socket_status[i] == Relay_OFF) {
MicoGpioOutputHigh(relay[i]);
} else {
MicoGpioOutputLow(relay[i]);
}
}
user_config->socket_status[i] = on >= 0 ? on : (user_config->socket_status[i] == 0 ? 1 : 0);
if (RelayOut() && user_config->power_led_enabled) {
UserLedSet(1);
} else {
UserLedSet(0);
}
}
/*
* 设置所有继电器开关
* y: 0:全部关 1:全部开
*
*/
void UserRelaySetAll(char y) {
int i;
for (i = 0; i < SOCKET_NUM; i++)
UserRelaySet(i, y);
}
static void KeyEventHandler(int num, boolean longPress) {
key_log("WARNGIN:Power key %s %d %s", !longPress ? "quick clicked" : "longPressed", num,
num > 1 ? (longPress ? "seconds" : "times") : (longPress ? "second" : "time"));
if (num > 30 || num <= 0)
return;
int function = !longPress ? get_short_func(user_config->user[num]) : get_long_func(
user_config->user[num]);key_log("WARNGIN:%s", get_func_name(function));
switch (function) {
case SWITCH_ALL_SOCKETS:
if (RelayOut()) {
UserRelaySetAll(0);
} else {
UserRelaySetAll(1);
}
mico_system_context_update(sys_config);
for (int i = 0; i < SOCKET_NUM; i++) {
UserMqttSendSocketState(i);
}
UserMqttSendTotalSocketState();
break;
case SWITCH_SOCKET_1:
case SWITCH_SOCKET_2:
case SWITCH_SOCKET_3:
case SWITCH_SOCKET_4:
case SWITCH_SOCKET_5:
case SWITCH_SOCKET_6:
UserRelaySet(user_config->user[num] - 1, Relay_TOGGLE);
UserMqttSendSocketState(user_config->user[num] - 1);
UserMqttSendTotalSocketState();
mico_system_context_update(sys_config);
break;
case SWITCH_LED_ENABLE:
MQTT_LED_ENABLED = MQTT_LED_ENABLED == 0 ? 1 : 0;
if (RelayOut() && MQTT_LED_ENABLED) {
UserLedSet(1);
} else {
UserLedSet(0);
}
UserMqttSendLedState();
mico_system_context_update(sys_config);
break;
case REBOOT_SYSTEM:
MicoSystemReboot();
break;
case CONFIG_WIFI:
StartLedBlink(3);
micoWlanSuspendStation();
ApInit(true);
break;
case RESET_SYSTEM:
StartLedBlink(8);
mico_system_context_restore(sys_config);
mico_rtos_thread_sleep(1);
MicoSystemReboot();
break;
default:
break;
}
}
mico_timer_t user_key_timer;
// 全局静态变量声明
static uint8_t click_count = 0;
static mico_timer_t click_end_timer;
uint16_t key_time = 0;
static mico_timer_t led_blink_timer;
static bool timer_initialized = false;
static uint8_t total_blinks = 0;
static uint8_t blink_counter = 0;
static bool led_state = false;
#define BUTTON_LONG_PRESS_TIME 10 //100ms*10=1s
// 定时器回调
static void _led_blink_timer_handler(void *arg)
{
if (blink_counter >= total_blinks) {
UserLedSet(0); // 闪烁完成,灭灯
mico_stop_timer(&led_blink_timer);
mico_deinit_timer(&led_blink_timer);
timer_initialized = false;
return;
}
led_state = !led_state;
UserLedSet(led_state ? 1 : 0);
blink_counter++;
}
// 安全重入的启动函数
void StartLedBlink(uint8_t times)
{
if (times == 0) return;
// 如果之前已启动,先停止并清理
if (timer_initialized) {
mico_stop_timer(&led_blink_timer);
mico_deinit_timer(&led_blink_timer);
timer_initialized = false;
}
total_blinks = times * 2;
blink_counter = 0;
led_state = false;
mico_init_timer(&led_blink_timer, 100, _led_blink_timer_handler, NULL);
mico_start_timer(&led_blink_timer);
timer_initialized = true;
}
static void ClickEndTimeoutHandler(void *arg) {
if (click_count <= 0) {
click_count = 0;
return;
}
KeyEventHandler(click_count,false);
click_count = 0;
}
static void KeyTimeoutHandler(void *arg) {
if (childLockEnabled)
return;
static char key_trigger, key_continue;
static uint8_t key_time = 0;
char tmp = ~(0xfe | MicoGpioInputGet(Button));
key_trigger = tmp & (tmp ^ key_continue);
key_continue = tmp;
if (key_trigger != 0)
key_time = 0;
if (key_continue != 0) {
key_time++;
// if (key_time > BUTTON_LONG_PRESS_TIME) {
// if (key_time == 50) {
// KeyLong5sPress();
// } else if (key_time > 50 && key_time < 57) {
// switch (key_time) {
// case 51:
// UserLedSet(1);
// break;
// case 52:
// UserLedSet(0);
// break;
// case 53:
// UserLedSet(1);
// break;
// case 54:
// UserLedSet(0);
// break;
// case 55:
// UserLedSet(1);
// break;
// case 56:
// UserLedSet(0);
// break;
// }
// } else if (key_time == 57) {
// UserLedSet(RelayOut() && user_config->power_led_enabled);
// } else if (key_time == 100) {
// KeyLong10sPress();
// } else if (key_time == 102) {
// UserLedSet(1);
// } else if (key_time == 103) {
// UserLedSet(0);
// key_time = 101;
// }
// }
} else {
if (key_time < BUTTON_LONG_PRESS_TIME) {
click_count++;
// 重启 click_end_timer300ms
mico_rtos_stop_timer(&click_end_timer);
mico_rtos_start_timer(&click_end_timer);
} else {
KeyEventHandler(key_time/10,true);
}
mico_rtos_stop_timer(&user_key_timer);
}
}
static void KeyFallingIrqHandler(void *arg) {
mico_rtos_start_timer(&user_key_timer);
}
void KeyInit(void) {
MicoGpioInitialize(Button, INPUT_PULL_UP);
mico_rtos_init_timer(&user_key_timer, 100, KeyTimeoutHandler, NULL);
mico_rtos_init_timer(&click_end_timer, 400, ClickEndTimeoutHandler, NULL);
MicoGpioEnableIRQ(Button, IRQ_TRIGGER_FALLING_EDGE, KeyFallingIrqHandler, NULL);
}