helloyifa 31f179cb76 init
2025-05-15 14:19:56 +08:00

419 lines
12 KiB
C
Executable File
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 "bk_gpio.h"
#include <os/os.h>
#include <os/mem.h>
#include <common/bk_kernel_err.h>
#include <driver/gpio.h>
#include <driver/hal/hal_gpio_types.h>
#include "gpio_driver.h"
#include <led_blink.h>
#include <string.h>
#include <components/log.h>
#define TAG "led_blink"
#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__)
#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__)
#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__)
#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__)
static LedControlBlock led_pool[MAX_LED_NUM];
static beken_mutex_t led_mutex = NULL;
typedef struct {
int led1; // 第一个LED句柄
int led2; // 第二个LED句柄
beken_timer_t timer; // 共享定时器
uint32_t interval; // 交替间隔
bool current_state; // 当前主导状态
} AlternateGroup;
static AlternateGroup s_alt_group;
static int led_handle_1 = 0;
static int led_handle_2 = 0;
static bool s_timer_initialized = false;
static int led_register(uint8_t gpio);
static void led_set_state(uint8_t led_handle, LedState new_state, uint32_t time);
static void led_unregister(uint8_t led_handle);
static void led_set_alternate(uint8_t led_handle_1, uint8_t led_handle_2, uint32_t interval_ms);
static void led_vote_error(uint8_t led_handle,ErrorType err_type);
static void led_resolve_error(uint8_t led_handle,ErrorType err_type);
static void update_active_error(LedControlBlock* led);
static void restore_normal_state(LedControlBlock* led);
static void alternate_timer_cb(void *arg) {
rtos_lock_mutex(&led_mutex);
// 交替状态
s_alt_group.current_state = !s_alt_group.current_state;
// 更新LED1状态
LedControlBlock* led_1 = &led_pool[s_alt_group.led1];
led_1->led_status = s_alt_group.current_state;
if (led_1->led_status == 0)
{
bk_gpio_set_value(led_1->gpio_num,0x0);
} else {
bk_gpio_set_value(led_1->gpio_num,0x2);
}
// 更新LED2状态取反
LedControlBlock* led_2 = &led_pool[s_alt_group.led2];
led_2->led_status = !s_alt_group.current_state;
if (led_2->led_status == 0)
{
bk_gpio_set_value(led_2->gpio_num,0x0);
} else {
bk_gpio_set_value(led_2->gpio_num,0x2);
}
rtos_unlock_mutex(&led_mutex);
}
//设置交替闪
static void led_set_alternate(uint8_t led_handle_1, uint8_t led_handle_2, uint32_t interval_ms) {
bk_err_t ret;
// 参数校验
if(led_handle_1 == led_handle_2 || led_handle_1 <0 || led_handle_2 <0 ||
led_handle_1 >= MAX_LED_NUM || led_handle_2 >= MAX_LED_NUM) return;
if((led_pool[led_handle_1].state == LED_ALTERNATE) && (led_pool[led_handle_2].state == LED_ALTERNATE))
return;
rtos_lock_mutex(&led_mutex);
// 配置交替组
s_alt_group.led1 = led_handle_1;
s_alt_group.led2 = led_handle_2;
s_alt_group.interval = interval_ms;
// 初始化LED状态
led_pool[led_handle_1].state = LED_ALTERNATE;
led_pool[led_handle_2].state = LED_ALTERNATE;
led_pool[led_handle_1].alt_partner = led_handle_2;
led_pool[led_handle_2].alt_partner = led_handle_1;
// 创建/重置定时器
if (!s_timer_initialized)
{
s_timer_initialized = true;
ret = rtos_init_timer(&s_alt_group.timer,interval_ms, alternate_timer_cb, NULL);
BK_ASSERT(kNoErr == ret);
}
// 强制设置初始状态
s_alt_group.current_state = true;
bk_gpio_set_value(led_pool[led_handle_1].gpio_num, 0x2);
bk_gpio_set_value(led_pool[led_handle_2].gpio_num, 0x0);
ret = rtos_start_timer(&s_alt_group.timer);
BK_ASSERT(kNoErr == ret);
rtos_unlock_mutex(&led_mutex);
}
static void timer_callback(void *arg) {
int led_handle = (int)arg;
LedControlBlock* led = &led_pool[led_handle];
bool should_stop = false;
if (led->blink_duration == LED_LAST_FOREVER)
{
should_stop = false;
}else if(led->blink_duration >= 0)
{
uint32_t now = rtos_get_time();
if (now - led->blink_start >= led->blink_duration)
{
should_stop = true;
}
}
if (led->active_error != ERROR_TYPE_COUNT)
{
LOGI("enter the anomaly\r\n");
led->led_status = !led->led_status;
if (led->led_status == 1)
{
bk_gpio_set_value(led->gpio_num,0x2);
} else {
bk_gpio_set_value(led->gpio_num,0x0);
}
}else if (should_stop)
{
LOGI("blink time's up\r\n");
rtos_stop_timer(&led->timer);
bk_gpio_set_value(led->gpio_num,0x0);
led->state = LED_OFF;
}else if(led->state == LED_FAST_BLINK || led->state == LED_SLOW_BLINK)
{
led->led_status = !led->led_status;
if (led->led_status == 1)
{
bk_gpio_set_value(led->gpio_num,0x2);
} else {
bk_gpio_set_value(led->gpio_num,0x0);
}
}
}
void led_driver_init() {
int ret = rtos_init_mutex(&led_mutex);
BK_ASSERT(kNoErr == ret);
memset(led_pool, 0, sizeof(led_pool));
led_handle_1 = led_register(RED_LED);
led_handle_2 = led_register(GREEN_LED);
}
int led_register(uint8_t gpio) {
bk_err_t ret;
rtos_lock_mutex(&led_mutex);
// 查找空闲控制块
for(int i=0; i<MAX_LED_NUM; i++){
if(led_pool[i].gpio_num == 0){
led_pool[i].gpio_num = gpio;
led_pool[i].active_error = ERROR_TYPE_COUNT;
ret = rtos_init_timer(&led_pool[i].timer,100, timer_callback, (void*)i);
BK_ASSERT(kNoErr == ret);
rtos_unlock_mutex(&led_mutex);
return i; // 返回LED句柄
}
}
rtos_unlock_mutex(&led_mutex);
return -1; // 注册失败
}
static void led_set_state(uint8_t led_handle, LedState new_state, uint32_t time) {
if(led_handle < 0 || led_handle >= MAX_LED_NUM)
return;
rtos_lock_mutex(&led_mutex);
LedControlBlock* led = &led_pool[led_handle];
if(led->state == LED_ALTERNATE && new_state != LED_ALTERNATE) {
// 停止交替定时器
if(s_alt_group.led1 == led_handle ||
s_alt_group.led2 == led_handle) {
rtos_stop_timer(&s_alt_group.timer);
}
//Another LED status clear
bk_gpio_set_value(led_pool[led->alt_partner].gpio_num, 0x0);
led_pool[led->alt_partner].state = LED_OFF;
// 解除伙伴关系
if(led->alt_partner != -1) {
led_pool[led->alt_partner].alt_partner = -1;
led->alt_partner = -1;
}
}
if (led->active_error == ERROR_TYPE_COUNT){
led->state = new_state;
switch (new_state) {
case LED_OFF:
rtos_stop_timer(&led->timer);
bk_gpio_set_value(led->gpio_num,0x0);
break;
case LED_ON:
led->blink_duration = time;
led->blink_start = rtos_get_time();
rtos_start_timer(&led->timer);
bk_gpio_set_value(led->gpio_num,0x2);
break;
case LED_FAST_BLINK:
led->interval = LED_FAST_BLINK_TIME;
led->blink_duration = time;
led->blink_start = rtos_get_time();
rtos_change_period(&led->timer, LED_FAST_BLINK_TIME);
rtos_start_timer(&led->timer);
break;
case LED_SLOW_BLINK:
led->interval = LED_SLOW_BLINK_TIME;
led->blink_duration = time;
led->blink_start = rtos_get_time();
rtos_change_period(&led->timer, LED_SLOW_BLINK_TIME);
rtos_start_timer(&led->timer);
break;
default:
break;
}
}
rtos_unlock_mutex(&led_mutex);
}
void led_unregister(uint8_t led_handle) {
if(led_handle < 0 || led_handle >= MAX_LED_NUM) return;
rtos_lock_mutex(&led_mutex);
rtos_deinit_timer(&led_pool[led_handle].timer);
memset(&led_pool[led_handle], 0, sizeof(LedControlBlock));
rtos_unlock_mutex(&led_mutex);
}
void led_vote_error(uint8_t led_handle, ErrorType err_type) {
if (led_handle < 0 || led_handle >= MAX_LED_NUM)
{
LOGE("error's led_handle , led_handle is %d\r\n",led_handle);
return;
}
rtos_lock_mutex(&led_mutex);
LedControlBlock* led = &led_pool[led_handle];
// 对应错误计数器增加
if (led->error_counts[err_type]++ == 0) {
// 首次投票此类型错误,可能触发状态变更
update_active_error(led);
}
rtos_unlock_mutex(&led_mutex);
}
void led_resolve_error(uint8_t led_handle, ErrorType err_type) {
if (led_handle < 0 || led_handle >= MAX_LED_NUM) return;
rtos_lock_mutex(&led_mutex);
LedControlBlock* led = &led_pool[led_handle];
if (led->error_counts[err_type] > 0 && --led->error_counts[err_type] == 0) {
// 该类型错误计数器归零,重新评估状态
update_active_error(led);
}
rtos_unlock_mutex(&led_mutex);
}
static void update_active_error(LedControlBlock* led) {
// 确定当前最高优先级错误
ErrorType new_active = ERROR_TYPE_COUNT;
for (int i = 0; i < ERROR_TYPE_COUNT; i++) {
if (led->error_counts[i] > 0) {
new_active = (ErrorType)i;
break; // 按优先级顺序遍历,第一个非零即最高
}
}
// 状态切换处理
if (new_active != led->active_error) {
rtos_stop_timer(&led->timer); // 停止当前定时器
if (new_active != ERROR_TYPE_COUNT) {
// 切换到新错误类型
led->active_error = new_active;
const int period = (new_active == ERROR_CRITICAL) ? LED_FAST_BLINK_TIME : LED_SLOW_BLINK_TIME;
os_printf("period is %d\r\n",period);
rtos_change_period(&led->timer, period);
rtos_start_timer(&led->timer);
led->state = (new_active == ERROR_CRITICAL) ? LED_FAST_BLINK : LED_SLOW_BLINK;
} else {
// 无错误,恢复正常状态
LOGI("Abnormal recovery\r\n");
restore_normal_state(led);
}
}
}
static void restore_normal_state(LedControlBlock* led) {
led->active_error = ERROR_TYPE_COUNT;
if (led->blink_duration > 0) {
// 重新启动自动熄灭计时
int period = led->interval;
led->blink_start = rtos_get_time();
rtos_change_period(&led->timer, period);
rtos_start_timer(&led->timer);
} else {
bk_gpio_set_value(led->gpio_num,0x0);
}
}
void led_app_set(led_operate_t oper, uint32_t time)
{
LOGI("%s:oper=%d,t=%d\r\n", __func__, oper, time);
switch(oper)
{
case LED_OFF_GREEN:
led_set_state(led_handle_2,LED_OFF,0);
break;
case LED_ON_GREEN:
led_set_state(led_handle_2,LED_ON,time);
break;
case LED_FAST_BLINK_GREEN:
led_set_state(led_handle_2,LED_FAST_BLINK,time);
break;
case LED_SLOW_BLINK_GREEN:
led_set_state(led_handle_2,LED_SLOW_BLINK,time);
break;
case LED_OFF_RED:
led_set_state(led_handle_1,LED_OFF,0);
break;
case LED_ON_RED:
led_set_state(led_handle_1,LED_ON,time);
break;
case LED_FAST_BLINK_RED:
led_set_state(led_handle_1,LED_FAST_BLINK,time);
break;
case LED_SLOW_BLINK_RED:
led_set_state(led_handle_1,LED_SLOW_BLINK,time);
break;
case LED_REG_GREEN_ALTERNATE:
led_set_alternate(led_handle_1,led_handle_2,500);
break;
case LED_REG_GREEN_ALTERNATE_OFF:
led_set_state(led_handle_1,LED_OFF,0);
led_set_state(led_handle_2,LED_OFF,0);
break;
case LED_ERROR_CRITICAL:
led_vote_error(led_handle_1,ERROR_CRITICAL);
break;
case LED_ERROR_WARNING:
led_vote_error(led_handle_1,ERROR_WARNING);
break;
case LED_ERROR_CRITICAL_CLOSE:
led_resolve_error(led_handle_1,ERROR_CRITICAL);
break;
case LED_ERROR_WARNING_CLOSE:
led_resolve_error(led_handle_1,ERROR_WARNING);
break;
default:
break;
}
}