Files
chrg/apps/chrg/applications/bsp/chrg_led.c
T
2025-11-18 00:40:02 +08:00

353 lines
9.9 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.
/****************************************************************************
文件名称 : chrg_led.c
完成日期 :
当前版本号 : V1.0
主要功能 : 采用系统软件定时器驱动多路GPIO
LED灯,实现LED等工作模式初始化,闪烁方式等的功能。
版本历史 : 创建原始版本
说明 :
******************************************************************************/
#include <rtthread.h>
#include "chrg_led.h"
#define LOG_TAG "chrg.led"
#define DBG_LEVEL DBG_LOG
#include <rtdbg.h>
struct chrg_led_t chrgleds[TOTAL_LEDS] = {
[IDX_LED1] = {
.index = IDX_LED1,
.pin_name = PIN_NAME_LED1,
.pin_base = PIN_LED1,
.pin_mode = PIN_MODE_OUTPUT,
.pin_value = PIN_HIGH,
.tmr_name = TMR_NAME_LED1,
.tmr_fd = RT_NULL,
.tmr_stage = PIN_STAGE_IDLE,
.tmr_millis_on = PULSE_TIME*8,
.tmr_millis_off = PULSE_TIME*8,
.tmr_times = 1,
.tmr_cnt = 0,
},
[IDX_LED2] = {
.index = IDX_LED2,
.pin_name = PIN_NAME_LED2,
.pin_base = PIN_LED2,
.pin_mode = PIN_MODE_OUTPUT,
.pin_value = PIN_LOW,
.tmr_name = TMR_NAME_LED2,
.tmr_fd = RT_NULL,
.tmr_stage = PIN_STAGE_IDLE,
.tmr_millis_on = PULSE_TIME*8,
.tmr_millis_off = PULSE_TIME*8,
.tmr_times = 1,
.tmr_cnt = 0,
},
[IDX_LED3] = {
.index = IDX_LED3,
.pin_name = PIN_NAME_LED3,
.pin_base = PIN_LED3,
.pin_mode = PIN_MODE_OUTPUT,
.pin_value = PIN_LOW,
.tmr_name = TMR_NAME_LED3,
.tmr_fd = RT_NULL,
.tmr_stage = PIN_STAGE_IDLE,
.tmr_millis_on = PULSE_TIME*8,
.tmr_millis_off = PULSE_TIME*8,
.tmr_times = 1,
.tmr_cnt = 0,
}
};
/*****************************************************************
函数名称: chrg_led_get
函数描述: 读取led pin管脚状态值。
输入参数: index:灯编号
输出参数: -
返回说明: <0: 异常,>=0: 状态值
其它说明: -
*****************************************************************/
rt_int32_t chrg_led_get (eIDX_LED index)
{
if (index >= TOTAL_LEDS) {
return -1;
}
struct chrg_led_t *pLED = &chrgleds[index];
pLED->pin_value = rt_pin_read(pLED->pin_base);
return pLED->pin_value;
}
/*****************************************************************
函数名称: chrg_led_set
函数描述: 设置led pin管脚状态值。
输入参数: *pLED: led pin定时器信息 value: 值
输出参数: -
返回说明: <0: 异常,=0: 正常操作
其它说明: -
*****************************************************************/
rt_int32_t chrg_led_set (struct chrg_led_t *pLED, rt_uint8_t value)
{
pLED->pin_value = value;
rt_pin_write(pLED->pin_base, pLED->pin_value);
return 0;
}
/*****************************************************************
函数名称: chrg_led_toggle
函数描述: led pin管脚翻转。
输入参数: index:灯编号
输出参数: -
返回说明: <0: 异常,=0: 正常操作
其它说明: -
*****************************************************************/
rt_int32_t chrg_led_toggle (eIDX_LED index)
{
if (index >= TOTAL_LEDS) {
return -1;
}
struct chrg_led_t *pLED = &chrgleds[index];
pLED->pin_value = !pLED->pin_value;
rt_pin_write(pLED->pin_base, pLED->pin_value);
return 0;
}
/*****************************************************************
函数名称: chrg_led_timer_set_on
函数描述: 设定状态高的延时。
输入参数: *pLED: led pin定时器信息
输出参数: -
返回说明: <0: 异常,=0: 正常操作
其它说明: -
*****************************************************************/
static rt_int32_t chrg_led_timer_set_on (struct chrg_led_t *pLED)
{
return rt_timer_control(pLED->tmr_fd, RT_TIMER_CTRL_SET_TIME, (void *)&pLED->tmr_millis_on);
}
/*****************************************************************
函数名称: chrg_led_timer_set_off
函数描述: 设定状态低的延时。
输入参数: *pLED: led pin定时器信息
输出参数: -
返回说明: <0: 异常,=0: 正常操作
其它说明: -
*****************************************************************/
static rt_int32_t chrg_led_timer_set_off (struct chrg_led_t *pLED)
{
return rt_timer_control(pLED->tmr_fd, RT_TIMER_CTRL_SET_TIME, (void *)&pLED->tmr_millis_off);
}
/*****************************************************************
函数名称: chrg_led_pulsing
函数描述: led pin定时器执行管脚状态设置。
输入参数: *pLED: led pin定时器信息, state: 流转状态
输出参数: -
返回说明: <0: 异常,=0: 正常操作
其它说明: -
*****************************************************************/
rt_int32_t chrg_led_pulsing (struct chrg_led_t *pLED, rt_uint8_t state)
{
rt_int32_t ret = 0;
if (state == PULSE_OFF) {
pLED->tmr_stage = PIN_STAGE_IDLE;
chrg_led_set(pLED, PIN_HIGH);
} else {
if (pLED->tmr_millis_on == HOLD_ZERO) { // 常低
pLED->tmr_stage = PIN_STAGE_IDLE;
rt_timer_stop(pLED->tmr_fd);
chrg_led_set(pLED, PIN_HIGH);
} else if (pLED->tmr_millis_off == HOLD_ZERO) { // 常高
pLED->tmr_stage = PIN_STAGE_IDLE;
chrg_led_set(pLED, PIN_LOW);
} else { // 交替
if (pLED->tmr_stage == PIN_STAGE_IDLE) {
pLED->tmr_stage = PIN_STAGE_ON;
chrg_led_set(pLED, PIN_LOW);
chrg_led_timer_set_on(pLED);
ret = rt_timer_start(pLED->tmr_fd);
}
}
}
return ret;
}
/*****************************************************************
函数名称: chrg_led_timer_timeout_callback
函数描述: led pin定时器回调操作。
输入参数: *parameterled pin定时器信息。
输出参数: -
返回说明: -
其它说明: -
*****************************************************************/
static void chrg_led_timer_timeout_callback (void* parameter)
{
struct chrg_led_t *pLED = (struct chrg_led_t *)parameter;
if (pLED->tmr_stage == PIN_STAGE_ON) {
pLED->tmr_stage = PIN_STAGE_OFF;
chrg_led_set(pLED, PIN_HIGH);
chrg_led_timer_set_off(pLED);
rt_timer_start(pLED->tmr_fd);
} else if (pLED->tmr_stage == PIN_STAGE_OFF) {
pLED->tmr_stage = PIN_STAGE_IDLE;
if ((pLED->tmr_times == TIMES_ALWAYS)&&(pLED->tmr_millis_off != HOLD_ZERO)) { // 保持闪烁
pLED->tmr_stage = PIN_STAGE_ON;
chrg_led_set(pLED, PIN_LOW);
chrg_led_timer_set_on(pLED);
rt_timer_start(pLED->tmr_fd);
} else { // 计数闪烁
if (++pLED->tmr_cnt >= pLED->tmr_times) {
pLED->tmr_cnt = 0;
rt_timer_stop(pLED->tmr_fd);
} else {
pLED->tmr_stage = PIN_STAGE_ON;
chrg_led_set(pLED, PIN_LOW);
chrg_led_timer_set_on(pLED);
rt_timer_start(pLED->tmr_fd);
}
}
}
}
/*****************************************************************
函数名称: chrg_led_timer_start
函数描述: 启动led pin定时器。
输入参数: index:灯编号
输出参数: -
返回说明: <0: 异常,=0: 正常操作
其它说明: -
*****************************************************************/
static rt_int32_t chrg_led_timer_start (eIDX_LED index)
{
if (index >= TOTAL_LEDS) {
return -1;
}
struct chrg_led_t *pLED = RT_NULL;
pLED = &chrgleds[index];
pLED->tmr_fd = rt_timer_create(pLED->tmr_name, chrg_led_timer_timeout_callback,
pLED, pLED->tmr_millis_on, RT_TIMER_FLAG_ONE_SHOT);
if (pLED->tmr_fd == RT_NULL) {
LOG_E("tmr create '%s' failed.", pLED->tmr_name);
return -1;
}
return 0;
}
/*****************************************************************
函数名称: chrg_led_timer_delete
函数描述: 删除led pin定时器。
输入参数: index:灯编号
输出参数: -
返回说明: <0: 异常,=0: 正常操作
其它说明: -
*****************************************************************/
rt_int32_t chrg_led_timer_delete (eIDX_LED index)
{
if (index >= TOTAL_LEDS) {
return -1;
}
return rt_timer_delete(chrgleds[index].tmr_fd);
}
/*****************************************************************
函数名称: chrg_led_show
函数描述: 控制指定灯的工作模式。
输入参数: index:灯编号, times:单次/循环, on:亮延时 off:灭延时
输出参数: -
返回说明: <0: 异常,=0: 正常操作
其它说明: -
*****************************************************************/
static rt_int32_t chrg_led_show (struct chrg_led_t *pLED, rt_uint32_t times, rt_uint32_t on, rt_uint32_t off)
{
rt_int32_t ret = 0;
pLED->tmr_millis_on = on;
pLED->tmr_millis_off = off;
pLED->tmr_times = times;
pLED->tmr_cnt = 0;
if (pLED->tmr_millis_on == HOLD_ZERO) {
ret = chrg_led_pulsing(pLED, PULSE_OFF);
} else {
ret = chrg_led_pulsing(pLED, PULSE_ON);
}
return ret;
}
/*****************************************************************
函数名称: chrg_led_flashing
函数描述: 控制指定灯的工作模式。
输入参数: index:灯编号, times:单次/循环, on:亮延时 off:灭延时
输出参数: -
返回说明: <0: 异常,=0: 正常操作
其它说明: -
*****************************************************************/
rt_int32_t chrg_led_flashing (eIDX_LED index, rt_uint32_t times, rt_uint32_t on, rt_uint32_t off)
{
rt_int32_t ret = -1;
struct chrg_led_t *pLED = NULL;
if (index < TOTAL_LEDS) {
pLED = &chrgleds[index];
ret = chrg_led_show(pLED, times, on, off);
}
return ret;
}
/*****************************************************************
函数名称: chrg_leds_init
函数描述: 启动多个软件定时,用于管理LED灯工作模式。
输入参数: -
输出参数: -
返回说明: <0: 异常,=0: 正常操作
其它说明: -
*****************************************************************/
static int chrg_leds_init (void)
{
rt_uint8_t i = 0;
struct chrg_led_t *pLED = RT_NULL;
for (i = 0; i < TOTAL_LEDS; i++) {
pLED = &chrgleds[i];
rt_pin_mode(pLED->pin_base, pLED->pin_mode);
if (pLED->pin_mode == PIN_MODE_OUTPUT) {
pLED->pin_value = PIN_HIGH;
rt_pin_write(pLED->pin_base, pLED->pin_value);
}
chrg_led_timer_start((eIDX_LED)i);
}
chrg_led_flashing(IDX_LED1, TIMES_ALWAYS, PULSE_TIME*8, PULSE_TIME*8);
return 0;
}
INIT_ENV_EXPORT(chrg_leds_init);