756 lines
26 KiB
C
756 lines
26 KiB
C
#include "typedef.h"
|
||
#include "asm/pwm_led.h"
|
||
#include "system/includes.h"
|
||
#include "chgbox_ctrl.h"
|
||
#include "chargeIc_manage.h"
|
||
#include "chgbox_ui.h"
|
||
#include "app_config.h"
|
||
|
||
//使用timer推灯,灭灯才能进入低功耗
|
||
|
||
#if (TCFG_CHARGE_BOX_ENABLE)
|
||
|
||
#define LOG_TAG_CONST APP_CHGBOX
|
||
#define LOG_TAG "[CHGBOXUI]"
|
||
#define LOG_ERROR_ENABLE
|
||
#define LOG_DEBUG_ENABLE
|
||
#define LOG_INFO_ENABLE
|
||
#define LOG_DUMP_ENABLE
|
||
#define LOG_CLI_ENABLE
|
||
#include "debug.h"
|
||
|
||
#if (TCFG_CHARGE_BOX_UI_ENABLE && TCFG_CHGBOX_UI_TIMERLED)
|
||
|
||
//常亮、常暗、呼吸
|
||
enum {
|
||
GHGBOX_LED_MODE_ON,
|
||
GHGBOX_LED_MODE_OFF,
|
||
GHGBOX_LED_MODE_BRE,
|
||
CHGBOX_LED_MODE_FLASH,
|
||
};
|
||
|
||
//呼吸灯的步骤 渐亮--亮--渐暗--暗
|
||
enum {
|
||
SOFT_LED_STEP_UP = 0,
|
||
SOFT_LED_STEP_LIGHT,
|
||
SOFT_LED_STEP_DOWN,
|
||
SOFT_LED_STEP_DARK,
|
||
};
|
||
|
||
typedef struct _CHG_SOFT_PWM_LED {
|
||
//初始化,亮暗接口接口
|
||
void (*led_init)(void);
|
||
void (*led_on_off)(u8 on_off);
|
||
|
||
u16 bre_times; //呼吸次数,0xffff为循环
|
||
|
||
u16 up_times; //渐亮次数
|
||
u16 light_times; //亮次数
|
||
u16 down_times; //渐暗次数
|
||
u16 dark_times; //暗次数
|
||
|
||
u16 step_cnt;
|
||
u8 step; //步骤
|
||
|
||
u8 p_cnt; //占空比计数
|
||
u8 cur_duty; //当前占空比
|
||
u8 max_duty; //最大占空比,控制最大亮度
|
||
|
||
u8 busy; //忙标志,更换参数时作保护用
|
||
u8 idle; //LED可以进低功耗
|
||
|
||
u8 sp_flicker; //特殊闪烁标志(用于处理亮-->亮,暗-->暗变化时灯光无反应的现象)
|
||
u16 sp_flicker_cnt;//特殊闪烁维持时间
|
||
|
||
u8 mode; //亮灯模式
|
||
} CHG_SOFT_PWM_LED;
|
||
|
||
#define MC_TIMER_UNIT_US 30 //多少us起一次中断
|
||
#define SOFT_MC_PWM_MAX 128 //pwm周期(==MC_TIMER_UNIT_US * SOFT_MC_PWM_MAX 单位us)
|
||
#define BRIGHTNESS_MAX 40 //亮度0~100
|
||
|
||
//注意时间尺度,即是mc_clk初始化出来的时间
|
||
#define UP_TIMES_DEFAULT 50
|
||
#define DOWN_TIMES_DEFAULT 50
|
||
#define SP_FLICKER_CNT_DEFAULT 30 //特殊闪烁时长计数
|
||
|
||
|
||
CHG_SOFT_PWM_LED chgbox_led[CHG_LED_MAX];
|
||
|
||
//led亮的时候不能进入低功耗
|
||
static volatile u8 is_led_active = 0;
|
||
static u8 led_idle_query(void)
|
||
{
|
||
return (!is_led_active);
|
||
}
|
||
REGISTER_LP_TARGET(led_lp_target) = {
|
||
.name = "chgbox_led",
|
||
.is_idle = led_idle_query,
|
||
};
|
||
|
||
/*------------------------------------------------------------------------------------*/
|
||
/**@brief 设置灯为常亮、常暗模式
|
||
@param led_type: 灯序号
|
||
on_off: 1-->常亮 0-->常暗
|
||
sp_flicker:是否闪烁标志 1-->在亮--亮 暗--暗过程中取反一下
|
||
fade: 1-->快速响应 0-->渐变响应
|
||
@return 无
|
||
@note 把灯设置为 常亮/常暗 模式(默认同时设置其他灯为常暗)
|
||
*/
|
||
/*------------------------------------------------------------------------------------*/
|
||
void chgbox_set_led_stu(u8 led_type, u8 on_off, u8 sp_flicker, u8 fade)
|
||
{
|
||
//只开关一个灯,其他关掉
|
||
u8 i;
|
||
for (i = 0; i < CHG_LED_MAX; i++) {
|
||
chgbox_led[i].busy = 1;
|
||
|
||
if (led_type == i) {
|
||
|
||
//设置特殊闪烁
|
||
chgbox_led[i].sp_flicker = sp_flicker;
|
||
chgbox_led[i].sp_flicker_cnt = SP_FLICKER_CNT_DEFAULT;
|
||
|
||
if (on_off) {
|
||
if (fade) {
|
||
//要根据当前占空比,把cnt计算好,避免亮度突变
|
||
chgbox_led[i].step_cnt = chgbox_led[i].up_times * chgbox_led[i].cur_duty / chgbox_led[i].max_duty;
|
||
} else {
|
||
chgbox_led[i].step_cnt = 0;
|
||
chgbox_led[i].cur_duty = chgbox_led[i].max_duty;
|
||
chgbox_led[i].sp_flicker = 0;
|
||
}
|
||
chgbox_led[i].mode = GHGBOX_LED_MODE_ON; //常亮
|
||
chgbox_led[i].up_times = UP_TIMES_DEFAULT;
|
||
} else {
|
||
if (fade) {
|
||
//要根据当前占空比,把cnt计算好
|
||
chgbox_led[i].step_cnt = chgbox_led[i].down_times - chgbox_led[i].down_times * chgbox_led[i].cur_duty / chgbox_led[i].max_duty;
|
||
} else {
|
||
chgbox_led[i].step_cnt = 0;
|
||
chgbox_led[i].cur_duty = 0;
|
||
chgbox_led[i].sp_flicker = 0;
|
||
}
|
||
chgbox_led[i].mode = GHGBOX_LED_MODE_OFF; //常暗
|
||
chgbox_led[i].down_times = DOWN_TIMES_DEFAULT;
|
||
}
|
||
} else {
|
||
if (fade) {
|
||
chgbox_led[i].step_cnt = chgbox_led[i].down_times - chgbox_led[i].down_times * chgbox_led[i].cur_duty / chgbox_led[i].max_duty;
|
||
} else {
|
||
chgbox_led[i].step_cnt = 0;
|
||
chgbox_led[i].cur_duty = 0;
|
||
}
|
||
chgbox_led[i].mode = GHGBOX_LED_MODE_OFF; //其他灯常暗
|
||
chgbox_led[i].sp_flicker = 0;
|
||
chgbox_led[i].down_times = 20;
|
||
}
|
||
is_led_active = 1;
|
||
chgbox_led[i].idle = 0;
|
||
chgbox_led[i].bre_times = 0;
|
||
chgbox_led[i].busy = 0;
|
||
}
|
||
}
|
||
|
||
/*------------------------------------------------------------------------------------*/
|
||
/**@brief 设置灯为呼吸模式
|
||
@param led_type: 灯序号
|
||
speed_mode:闪烁参数选择,这里默认为快、慢两种
|
||
is_bre:是否为呼吸模式
|
||
time:呼吸/闪烁多少次
|
||
@return 无
|
||
@note 把灯设置为呼吸模式(默认同时其他灯为常暗)
|
||
*/
|
||
/*------------------------------------------------------------------------------------*/
|
||
void chgbox_set_led_bre(u8 led_type, u8 speed_mode, u8 is_bre, u16 time)
|
||
{
|
||
//只开关一个灯,其他关掉
|
||
u8 i;
|
||
for (i = 0; i < CHG_LED_MAX; i++) {
|
||
chgbox_led[i].busy = 1;
|
||
|
||
if (led_type == i) {
|
||
if (is_bre) {
|
||
chgbox_led[i].mode = GHGBOX_LED_MODE_BRE; //呼吸
|
||
} else {
|
||
chgbox_led[i].mode = CHGBOX_LED_MODE_FLASH; //闪烁
|
||
}
|
||
chgbox_led[i].bre_times = time; //循环
|
||
if (speed_mode == LED_FLASH_FAST) {
|
||
chgbox_led[i].up_times = 50;
|
||
chgbox_led[i].light_times = 10;
|
||
chgbox_led[i].down_times = 50;
|
||
chgbox_led[i].dark_times = 10;
|
||
} else if (speed_mode == LED_FLASH_SLOW) {
|
||
chgbox_led[i].up_times = 200;
|
||
chgbox_led[i].light_times = 40;
|
||
chgbox_led[i].down_times = 200;
|
||
chgbox_led[i].dark_times = 40;
|
||
}
|
||
//要根据当前占空比,把cnt计算好,
|
||
chgbox_led[i].step_cnt = chgbox_led[i].up_times * chgbox_led[i].cur_duty / chgbox_led[i].max_duty;
|
||
} else {
|
||
chgbox_led[i].mode = GHGBOX_LED_MODE_OFF; //常暗
|
||
chgbox_led[i].down_times = 20;
|
||
chgbox_led[i].step_cnt = chgbox_led[i].down_times - chgbox_led[i].down_times * chgbox_led[i].cur_duty / chgbox_led[i].max_duty;
|
||
chgbox_led[i].bre_times = 0;
|
||
}
|
||
is_led_active = 1;
|
||
chgbox_led[i].idle = 0;
|
||
chgbox_led[i].busy = 0;
|
||
}
|
||
}
|
||
|
||
/*------------------------------------------------------------------------------------*/
|
||
/**@brief 呼吸灯全暗
|
||
@param fade:是否淡入
|
||
@return 无
|
||
@note 把所有的灯设置为常暗模式
|
||
*/
|
||
/*------------------------------------------------------------------------------------*/
|
||
void chgbox_set_led_all_off(u8 fade)
|
||
{
|
||
u8 i;
|
||
for (i = 0; i < CHG_LED_MAX; i++) {
|
||
chgbox_led[i].busy = 1;
|
||
|
||
if (fade) {
|
||
chgbox_led[i].step_cnt = chgbox_led[i].down_times - chgbox_led[i].down_times * chgbox_led[i].cur_duty / chgbox_led[i].max_duty;
|
||
} else {
|
||
chgbox_led[i].step_cnt = 0;
|
||
chgbox_led[i].sp_flicker = 0;
|
||
chgbox_led[i].cur_duty = 0;
|
||
}
|
||
chgbox_led[i].mode = GHGBOX_LED_MODE_OFF; //常暗
|
||
chgbox_led[i].down_times = DOWN_TIMES_DEFAULT;
|
||
chgbox_led[i].bre_times = 0;
|
||
chgbox_led[i].idle = 0;
|
||
is_led_active = 1;
|
||
chgbox_led[i].busy = 0;
|
||
}
|
||
}
|
||
|
||
/*------------------------------------------------------------------------------------*/
|
||
/**@brief 呼吸灯全亮
|
||
@param fade:是否淡入
|
||
@return 无
|
||
@note 把所有的灯设置为常亮模式
|
||
*/
|
||
/*------------------------------------------------------------------------------------*/
|
||
void chgbox_set_led_all_on(u8 fade)
|
||
{
|
||
u8 i;
|
||
for (i = 0; i < CHG_LED_MAX; i++) {
|
||
chgbox_led[i].busy = 1;
|
||
is_led_active = 1;
|
||
if (fade) {
|
||
chgbox_led[i].step_cnt = chgbox_led[i].up_times * chgbox_led[i].cur_duty / chgbox_led[i].max_duty;
|
||
} else {
|
||
chgbox_led[i].step_cnt = 0;
|
||
chgbox_led[i].sp_flicker = 0;
|
||
chgbox_led[i].cur_duty = chgbox_led[i].max_duty;
|
||
}
|
||
chgbox_led[i].mode = GHGBOX_LED_MODE_ON; //常亮
|
||
chgbox_led[i].up_times = UP_TIMES_DEFAULT;
|
||
chgbox_led[i].bre_times = 0;
|
||
chgbox_led[i].idle = 0;
|
||
chgbox_led[i].busy = 0;
|
||
}
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////
|
||
////////////////////////////////////////////////////////////////////////
|
||
//硬件、软pwm驱动部分(时钟、占空比控制等)
|
||
//蓝灯初始化
|
||
static void chg_red_led_init()
|
||
{
|
||
#if (CHG_RED_LED_IO != NO_CONFIG_PORT)
|
||
gpio_set_die(CHG_RED_LED_IO, 1);
|
||
gpio_set_pull_down(CHG_RED_LED_IO, 0);
|
||
gpio_set_pull_up(CHG_RED_LED_IO, 0);
|
||
gpio_set_die(CHG_RED_LED_IO, 0);
|
||
gpio_set_dieh(CHG_RED_LED_IO, 0);
|
||
//初始化为暗态
|
||
gpio_direction_output(CHG_RED_LED_IO, !CHG_LED_MODE);
|
||
#endif
|
||
}
|
||
|
||
//蓝灯高低电平控制
|
||
//on_off:1:输出高平电 0:输出低电平
|
||
SEC(.chargebox_code)//频繁调用的放ram里
|
||
static void chg_set_red_led(u8 on_off)
|
||
{
|
||
#if CHG_RED_LED_IO != NO_CONFIG_PORT
|
||
u8 io_num;
|
||
io_num = CHG_RED_LED_IO % 16;
|
||
|
||
#if (CHG_LED_MODE == 0)
|
||
on_off = !on_off;
|
||
#endif
|
||
|
||
if (on_off) {
|
||
#if(CHG_RED_LED_IO <= IO_PORTA_15)
|
||
JL_PORTA->OUT |= BIT(io_num);
|
||
#elif(CHG_RED_LED_IO <= IO_PORTB_15)
|
||
JL_PORTB->OUT |= BIT(io_num);
|
||
#elif(CHG_RED_LED_IO <= IO_PORTC_15)
|
||
JL_PORTC->OUT |= BIT(io_num);
|
||
#elif(CHG_RED_LED_IO <= IO_PORTD_07)
|
||
JL_PORTD->OUT |= BIT(io_num);
|
||
#elif(CHG_RED_LED_IO == IO_PORT_DP)
|
||
JL_USB_IO->CON0 |= BIT(0);
|
||
#elif(CHG_RED_LED_IO == IO_PORT_DM)
|
||
JL_USB_IO->CON0 |= BIT(1);
|
||
#endif
|
||
} else {
|
||
#if(CHG_RED_LED_IO <= IO_PORTA_15)
|
||
JL_PORTA->OUT &= ~BIT(io_num);
|
||
#elif(CHG_RED_LED_IO <= IO_PORTB_15)
|
||
JL_PORTB->OUT &= ~BIT(io_num);
|
||
#elif(CHG_RED_LED_IO <= IO_PORTC_15)
|
||
JL_PORTC->OUT &= ~BIT(io_num);
|
||
#elif(CHG_RED_LED_IO <= IO_PORTD_07)
|
||
JL_PORTD->OUT &= ~BIT(io_num);
|
||
#elif(CHG_RED_LED_IO == IO_PORT_DP)
|
||
JL_USB_IO->CON0 &= ~BIT(0);
|
||
#elif(CHG_RED_LED_IO == IO_PORT_DM)
|
||
JL_USB_IO->CON0 &= ~BIT(1);
|
||
#endif
|
||
}
|
||
#endif
|
||
}
|
||
|
||
//绿灯初始化
|
||
static void chg_green_led_init()
|
||
{
|
||
#if (CHG_GREEN_LED_IO != NO_CONFIG_PORT)
|
||
gpio_set_die(CHG_GREEN_LED_IO, 1);
|
||
gpio_set_pull_down(CHG_GREEN_LED_IO, 0);
|
||
gpio_set_pull_up(CHG_GREEN_LED_IO, 0);
|
||
gpio_set_die(CHG_GREEN_LED_IO, 0);
|
||
gpio_set_dieh(CHG_GREEN_LED_IO, 0);
|
||
//初始化为暗态
|
||
gpio_direction_output(CHG_GREEN_LED_IO, !CHG_LED_MODE);
|
||
#endif
|
||
}
|
||
|
||
//绿灯高低电平控制
|
||
//on_off:1:输出高平电 0:输出低电平
|
||
SEC(.chargebox_code)//频繁调用的放ram里
|
||
static void chg_set_green_led(u8 on_off)
|
||
{
|
||
#if (CHG_GREEN_LED_IO != NO_CONFIG_PORT)
|
||
u8 io_num;
|
||
io_num = CHG_GREEN_LED_IO % 16;
|
||
|
||
#if (CHG_LED_MODE == 0)
|
||
on_off = !on_off;
|
||
#endif
|
||
|
||
if (on_off) {
|
||
#if(CHG_GREEN_LED_IO <= IO_PORTA_15)
|
||
JL_PORTA->OUT |= BIT(io_num);
|
||
#elif(CHG_GREEN_LED_IO <= IO_PORTB_15)
|
||
JL_PORTB->OUT |= BIT(io_num);
|
||
#elif(CHG_GREEN_LED_IO <= IO_PORTC_15)
|
||
JL_PORTC->OUT |= BIT(io_num);
|
||
#elif(CHG_GREEN_LED_IO <= IO_PORTD_07)
|
||
JL_PORTD->OUT |= BIT(io_num);
|
||
#elif(CHG_GREEN_LED_IO == IO_PORT_DP)
|
||
JL_USB_IO->CON0 |= BIT(0);
|
||
#elif(CHG_GREEN_LED_IO == IO_PORT_DM)
|
||
JL_USB_IO->CON0 |= BIT(1);
|
||
#endif
|
||
|
||
} else {
|
||
#if(CHG_GREEN_LED_IO <= IO_PORTA_15)
|
||
JL_PORTA->OUT &= ~BIT(io_num);
|
||
#elif(CHG_GREEN_LED_IO <= IO_PORTB_15)
|
||
JL_PORTB->OUT &= ~BIT(io_num);
|
||
#elif(CHG_GREEN_LED_IO <= IO_PORTC_15)
|
||
JL_PORTC->OUT &= ~BIT(io_num);
|
||
#elif(CHG_GREEN_LED_IO <= IO_PORTD_07)
|
||
JL_PORTD->OUT &= ~BIT(io_num);
|
||
#elif(CHG_GREEN_LED_IO == IO_PORT_DP)
|
||
JL_USB_IO->CON0 &= ~BIT(0);
|
||
#elif(CHG_GREEN_LED_IO == IO_PORT_DM)
|
||
JL_USB_IO->CON0 &= ~BIT(1);
|
||
#endif
|
||
}
|
||
#endif
|
||
}
|
||
|
||
//蓝灯初始化
|
||
static void chg_blue_led_init()
|
||
{
|
||
#if (CHG_BLUE_LED_IO != NO_CONFIG_PORT)
|
||
gpio_set_die(CHG_BLUE_LED_IO, 1);
|
||
gpio_set_pull_down(CHG_BLUE_LED_IO, 0);
|
||
gpio_set_pull_up(CHG_BLUE_LED_IO, 0);
|
||
gpio_direction_output(CHG_BLUE_LED_IO, 0);
|
||
gpio_set_die(CHG_BLUE_LED_IO, 0);
|
||
gpio_set_dieh(CHG_BLUE_LED_IO, 0);
|
||
//初始化为暗态
|
||
gpio_direction_output(CHG_BLUE_LED_IO, !CHG_LED_MODE);
|
||
#endif
|
||
}
|
||
|
||
//蓝灯高低电平控制
|
||
//on_off:1:输出高平电 0:输出低电平
|
||
SEC(.chargebox_code)
|
||
static void chg_set_blue_led(u8 on_off)
|
||
{
|
||
#if (CHG_BLUE_LED_IO != NO_CONFIG_PORT)
|
||
u8 io_num;
|
||
io_num = CHG_BLUE_LED_IO % 16;
|
||
|
||
#if (CHG_LED_MODE == 0)
|
||
on_off = !on_off;
|
||
#endif
|
||
|
||
if (on_off) {
|
||
#if(CHG_BLUE_LED_IO <= IO_PORTA_15)
|
||
JL_PORTA->OUT |= BIT(io_num);
|
||
#elif(CHG_BLUE_LED_IO <= IO_PORTB_15)
|
||
JL_PORTB->OUT |= BIT(io_num);
|
||
#elif(CHG_BLUE_LED_IO <= IO_PORTC_15)
|
||
JL_PORTC->OUT |= BIT(io_num);
|
||
#elif(CHG_BLUE_LED_IO <= IO_PORTD_07)
|
||
JL_PORTD->OUT |= BIT(io_num);
|
||
#elif(CHG_BLUE_LED_IO == IO_PORT_DP)
|
||
JL_USB_IO->CON0 |= BIT(0);
|
||
#elif(CHG_BLUE_LED_IO == IO_PORT_DM)
|
||
JL_USB_IO->CON0 |= BIT(1);
|
||
#endif
|
||
} else {
|
||
#if(CHG_BLUE_LED_IO <= IO_PORTA_15)
|
||
JL_PORTA->OUT &= ~BIT(io_num);
|
||
#elif(CHG_BLUE_LED_IO <= IO_PORTB_15)
|
||
JL_PORTB->OUT &= ~BIT(io_num);
|
||
#elif(CHG_BLUE_LED_IO <= IO_PORTC_15)
|
||
JL_PORTC->OUT &= ~BIT(io_num);
|
||
#elif(CHG_BLUE_LED_IO <= IO_PORTD_07)
|
||
JL_PORTD->OUT &= ~BIT(io_num);
|
||
#elif(CHG_BLUE_LED_IO == IO_PORT_DP)
|
||
JL_USB_IO->CON0 &= ~BIT(0);
|
||
#elif(CHG_BLUE_LED_IO == IO_PORT_DM)
|
||
JL_USB_IO->CON0 &= ~BIT(1);
|
||
#endif
|
||
}
|
||
#endif
|
||
}
|
||
|
||
/*------------------------------------------------------------------------------------*/
|
||
/**@brief 呼吸灯占空比控制
|
||
@param i:灯序号
|
||
@return 无
|
||
@note 根据常亮、常暗、呼吸等模式控制占空比
|
||
*/
|
||
/*------------------------------------------------------------------------------------*/
|
||
SEC(.chargebox_code)
|
||
static u8 soft_pwm_led_ctrl(u8 i)
|
||
{
|
||
u8 ret = 0;
|
||
switch (chgbox_led[i].mode) {
|
||
case GHGBOX_LED_MODE_ON: //常亮
|
||
if (chgbox_led[i].sp_flicker) { //暗一下(包括了渐暗+暗 两个过程)
|
||
if (chgbox_led[i].cur_duty > 0) {
|
||
chgbox_led[i].step_cnt++;
|
||
if (chgbox_led[i].step_cnt >= chgbox_led[i].down_times) {
|
||
chgbox_led[i].step_cnt = 0;
|
||
chgbox_led[i].cur_duty = 0;
|
||
} else {
|
||
chgbox_led[i].cur_duty = (chgbox_led[i].down_times - chgbox_led[i].step_cnt) * chgbox_led[i].max_duty / chgbox_led[i].down_times;
|
||
}
|
||
} else {
|
||
if (chgbox_led[i].sp_flicker_cnt) { //持续暗的时间
|
||
chgbox_led[i].sp_flicker_cnt--;
|
||
if (chgbox_led[i].sp_flicker_cnt == 0) {
|
||
chgbox_led[i].sp_flicker = 0; //结束暗一下流程
|
||
}
|
||
}
|
||
}
|
||
} else if (chgbox_led[i].cur_duty < chgbox_led[i].max_duty) {
|
||
chgbox_led[i].step_cnt++;
|
||
if (chgbox_led[i].step_cnt >= chgbox_led[i].up_times) {
|
||
chgbox_led[i].step_cnt = 0;
|
||
chgbox_led[i].cur_duty = chgbox_led[i].max_duty;
|
||
} else {
|
||
//这里为了避免灯光突变,根据改变前的亮度来计算了cnt
|
||
chgbox_led[i].cur_duty = chgbox_led[i].step_cnt * chgbox_led[i].max_duty / chgbox_led[i].up_times;
|
||
}
|
||
}
|
||
break;
|
||
case GHGBOX_LED_MODE_OFF://常暗
|
||
if (chgbox_led[i].sp_flicker) { //亮一下
|
||
if (chgbox_led[i].cur_duty < chgbox_led[i].max_duty) {
|
||
chgbox_led[i].step_cnt++;
|
||
if (chgbox_led[i].step_cnt >= chgbox_led[i].up_times) {
|
||
chgbox_led[i].step_cnt = 0;
|
||
chgbox_led[i].cur_duty = chgbox_led[i].max_duty;
|
||
} else {
|
||
//这里为了避免灯光突变,根据改变前的亮度来计算了cnt
|
||
chgbox_led[i].cur_duty = chgbox_led[i].step_cnt * chgbox_led[i].max_duty / chgbox_led[i].up_times;
|
||
}
|
||
} else {
|
||
if (chgbox_led[i].sp_flicker_cnt) { //持续亮的时间
|
||
chgbox_led[i].sp_flicker_cnt--;
|
||
if (chgbox_led[i].sp_flicker_cnt == 0) {
|
||
chgbox_led[i].sp_flicker = 0; //结束亮一下流程
|
||
}
|
||
}
|
||
}
|
||
} else if (chgbox_led[i].cur_duty > 0) {
|
||
chgbox_led[i].step_cnt++;
|
||
if (chgbox_led[i].step_cnt >= chgbox_led[i].down_times) {
|
||
chgbox_led[i].step_cnt = 0;
|
||
chgbox_led[i].cur_duty = 0;
|
||
} else {
|
||
//这里为了避免灯光突变,根据改变前的亮度来计算了cnt
|
||
chgbox_led[i].cur_duty = (chgbox_led[i].down_times - chgbox_led[i].step_cnt) * chgbox_led[i].max_duty / chgbox_led[i].down_times;
|
||
}
|
||
} else {
|
||
ret = 1;
|
||
}
|
||
break;
|
||
case GHGBOX_LED_MODE_BRE://呼吸灯模式
|
||
if (chgbox_led[i].bre_times == 0) {
|
||
ret = 1;
|
||
break;
|
||
}
|
||
|
||
if (chgbox_led[i].step == SOFT_LED_STEP_UP) {
|
||
chgbox_led[i].step_cnt++;
|
||
if (chgbox_led[i].step_cnt >= chgbox_led[i].up_times) { //当前段结束
|
||
chgbox_led[i].step_cnt = 0;
|
||
chgbox_led[i].step++; //进入下一个步骤
|
||
} else {
|
||
chgbox_led[i].cur_duty = chgbox_led[i].step_cnt * chgbox_led[i].max_duty / chgbox_led[i].up_times;
|
||
}
|
||
} else if (chgbox_led[i].step == SOFT_LED_STEP_LIGHT) {
|
||
chgbox_led[i].step_cnt++;
|
||
chgbox_led[i].cur_duty = chgbox_led[i].max_duty;
|
||
if (chgbox_led[i].step_cnt >= chgbox_led[i].light_times) {
|
||
chgbox_led[i].step_cnt = 0;
|
||
chgbox_led[i].step++;
|
||
}
|
||
} else if (chgbox_led[i].step == SOFT_LED_STEP_DOWN) {
|
||
chgbox_led[i].step_cnt++;
|
||
if (chgbox_led[i].step_cnt >= chgbox_led[i].down_times) {
|
||
chgbox_led[i].step_cnt = 0;
|
||
chgbox_led[i].step++;
|
||
} else {
|
||
chgbox_led[i].cur_duty = (chgbox_led[i].down_times - chgbox_led[i].step_cnt) * chgbox_led[i].max_duty / chgbox_led[i].down_times;
|
||
}
|
||
} else if (chgbox_led[i].step == SOFT_LED_STEP_DARK) {
|
||
chgbox_led[i].step_cnt++;
|
||
chgbox_led[i].cur_duty = 0;
|
||
if (chgbox_led[i].step_cnt >= chgbox_led[i].dark_times) {
|
||
chgbox_led[i].step_cnt = 0;
|
||
chgbox_led[i].step = 0; //重新开始下一次呼吸
|
||
if (chgbox_led[i].bre_times != 0xffff) { //非循环
|
||
chgbox_led[i].bre_times--; //呼吸次数递减
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case CHGBOX_LED_MODE_FLASH:
|
||
if (chgbox_led[i].bre_times == 0) {
|
||
ret = 1;
|
||
break;
|
||
}
|
||
if (chgbox_led[i].step == SOFT_LED_STEP_UP) {
|
||
chgbox_led[i].cur_duty = chgbox_led[i].max_duty;
|
||
chgbox_led[i].step_cnt++;
|
||
if (chgbox_led[i].step_cnt >= chgbox_led[i].up_times + chgbox_led[i].light_times) {
|
||
chgbox_led[i].step_cnt = 0;
|
||
chgbox_led[i].step = SOFT_LED_STEP_DOWN;
|
||
}
|
||
} else if (chgbox_led[i].step == SOFT_LED_STEP_DOWN) {
|
||
chgbox_led[i].cur_duty = 0;
|
||
chgbox_led[i].step_cnt++;
|
||
if (chgbox_led[i].step_cnt >= chgbox_led[i].down_times + chgbox_led[i].dark_times) {
|
||
chgbox_led[i].step_cnt = 0;
|
||
chgbox_led[i].step = SOFT_LED_STEP_UP;
|
||
if (chgbox_led[i].bre_times != 0xffff) { //非循环
|
||
chgbox_led[i].bre_times--; //次数递减
|
||
}
|
||
}
|
||
} else {
|
||
chgbox_led[i].bre_times = 0;
|
||
chgbox_led[i].cur_duty = 0;
|
||
}
|
||
break;
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
#define TIMER_USE_MC_PWM 0
|
||
#if TIMER_USE_MC_PWM == 0
|
||
#define JL_TIMERx JL_TIMER5
|
||
#define IRQ_TIMEX_IDX IRQ_TIME5_IDX
|
||
#define TIMERX_IOS_BIT 21
|
||
#define TIMERX_IOS_CLK 12000000
|
||
#endif
|
||
|
||
/*------------------------------------------------------------------------------------*/
|
||
/**@brief mc_clk中断回调
|
||
@param 无
|
||
@return 无
|
||
@note 用于循环所有的呼吸灯,包括亮暗控制,占空比设置等
|
||
*/
|
||
/*------------------------------------------------------------------------------------*/
|
||
SEC(.chargebox_code)
|
||
___interrupt
|
||
void soft_pwm_led_isr(void)
|
||
{
|
||
#if TIMER_USE_MC_PWM
|
||
JL_MCPWM->TMR0_CON |= BIT(10); //清pending
|
||
#else
|
||
JL_TIMERx->CON |= BIT(14);
|
||
#endif
|
||
u8 i, led_idle = 0;
|
||
|
||
for (i = 0; i < CHG_LED_MAX; i++) { //循环所有的灯
|
||
if (!chgbox_led[i].busy) {
|
||
if (chgbox_led[i].p_cnt < (chgbox_led[i].cur_duty)) { //占空比
|
||
chgbox_led[i].led_on_off(1); //亮
|
||
} else {
|
||
chgbox_led[i].led_on_off(0);
|
||
}
|
||
chgbox_led[i].p_cnt++;
|
||
if (chgbox_led[i].p_cnt >= SOFT_MC_PWM_MAX) { //完成一个PWM周期
|
||
chgbox_led[i].p_cnt = 0;
|
||
chgbox_led[i].idle = soft_pwm_led_ctrl(i);//占空比控制
|
||
}
|
||
}
|
||
led_idle += chgbox_led[i].idle;
|
||
}
|
||
if (led_idle == CHG_LED_MAX) {
|
||
is_led_active = 0;
|
||
}
|
||
}
|
||
|
||
#if TIMER_USE_MC_PWM
|
||
static const u32 timer_div_mc[] = {
|
||
1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768
|
||
};
|
||
#else
|
||
static const u32 timer_div_mc[] = {
|
||
1, 4, 16, 64, 1 * 2, 4 * 2, 16 * 2, 64 * 2, 1 * 256, 4 * 256, 16 * 256, 64 * 256, 1 * 2 * 256, 4 * 2 * 256, 16 * 2 * 256, 64 * 2 * 256
|
||
};
|
||
#endif
|
||
#define MC_MAX_TIME_CNT 0x7fff
|
||
#define MC_MIN_TIME_CNT 0x10
|
||
/*------------------------------------------------------------------------------------*/
|
||
/**@brief mc_clk的初始化
|
||
@param 无
|
||
@return 无
|
||
@note 初始clk,注册中断,MC_TIMER_UNIT_US 为起中断的时间,单位us
|
||
*/
|
||
/*------------------------------------------------------------------------------------*/
|
||
void mc_clk_init(void)
|
||
{
|
||
#if TIMER_USE_MC_PWM
|
||
//br25 没有mcpwm
|
||
u32 prd_cnt;
|
||
u8 index;
|
||
|
||
JL_MCPWM->TMR0_CON = BIT(10); //清pending,清其他bit
|
||
JL_MCPWM->MCPWM_CON0 = 0;
|
||
|
||
for (index = 0; index < (sizeof(timer_div_mc) / sizeof(timer_div_mc[0])); index++) {
|
||
prd_cnt = MC_TIMER_UNIT_US * (clk_get("lsb") / 1000000) / timer_div_mc[index];
|
||
if (prd_cnt > MC_MIN_TIME_CNT && prd_cnt < MC_MAX_TIME_CNT) {
|
||
break;
|
||
}
|
||
}
|
||
|
||
JL_MCPWM->TMR0_CNT = 0;
|
||
JL_MCPWM->TMR0_PR = prd_cnt;
|
||
JL_MCPWM->TMR0_CON |= index << 3; //分频系数
|
||
|
||
request_irq(IRQ_MCTMRX_IDX, 3, soft_pwm_led_isr, 0);
|
||
|
||
JL_MCPWM->TMR0_CON |= BIT(8); //允许定时溢出中断
|
||
JL_MCPWM->TMR0_CON |= BIT(0); //递增模式
|
||
|
||
JL_MCPWM->MCPWM_CON0 |= BIT(8); //只开mc timer 0
|
||
log_info("prd_cnt:%d,index:%d,t0:%x,MCP:%x\n", prd_cnt, index, JL_MCPWM->TMR0_CON, JL_MCPWM->MCPWM_CON0);
|
||
log_info("lsb:%d\n", clk_get("lsb"));
|
||
#else
|
||
u32 timer_clk;
|
||
u32 prd_cnt;
|
||
u8 index;
|
||
JL_TIMERx->CON = BIT(14);
|
||
JL_TIMERx->CNT = 0;
|
||
|
||
#if (TCFG_CLOCK_SYS_SRC == SYS_CLOCK_INPUT_PLL_RCL)
|
||
timer_clk = TIMERX_IOS_CLK;
|
||
#else
|
||
timer_clk = clk_get("timer");
|
||
#endif
|
||
|
||
for (index = 0; index < (sizeof(timer_div_mc) / sizeof(timer_div_mc[0])); index++) {
|
||
prd_cnt = MC_TIMER_UNIT_US * (timer_clk / 1000000) / timer_div_mc[index];
|
||
if (prd_cnt > MC_MIN_TIME_CNT && prd_cnt < MC_MAX_TIME_CNT) {
|
||
break;
|
||
}
|
||
}
|
||
//初始化timer
|
||
request_irq(IRQ_TIMEX_IDX, 3, soft_pwm_led_isr, 0);
|
||
JL_TIMERx->PRD = prd_cnt;
|
||
#if (TCFG_CLOCK_SYS_SRC == SYS_CLOCK_INPUT_PLL_RCL)
|
||
JL_IOMAP->CON0 |= BIT(TIMERX_IOS_BIT);
|
||
JL_TIMERx->CON = (index << 4) | BIT(0) | BIT(2);//省晶振使用pll12m为时钟源
|
||
#else
|
||
JL_TIMERx->CON = (index << 4) | (0b10 << 2) | (0b01 << 0);//OSC时钟
|
||
#endif
|
||
#endif
|
||
}
|
||
|
||
/*------------------------------------------------------------------------------------*/
|
||
/**@brief led呼吸灯初始化
|
||
@param 无
|
||
@return 无
|
||
@note 初始化每个led:渐亮、亮、渐暗、暗,最大亮度,对应IO的初始化.mc_clk的初始化,用于
|
||
控制pwm
|
||
*/
|
||
/*-----------------------------------------------------------------------------------*/
|
||
void chgbox_led_init(void)
|
||
{
|
||
u8 i;
|
||
for (i = 0; i < CHG_LED_MAX; i++) { //循环所有的灯
|
||
memset(&chgbox_led[i], 0x0, sizeof(CHG_SOFT_PWM_LED));
|
||
chgbox_led[i].up_times = UP_TIMES_DEFAULT;
|
||
chgbox_led[i].light_times = 100;
|
||
chgbox_led[i].down_times = DOWN_TIMES_DEFAULT;
|
||
chgbox_led[i].dark_times = 10;
|
||
chgbox_led[i].bre_times = 0;
|
||
|
||
//可根据需要修改初始化,但要把初始化与亮灭注册进来
|
||
if (i == CHG_LED_RED) {
|
||
chgbox_led[i].led_on_off = chg_set_red_led;
|
||
chgbox_led[i].led_init = chg_red_led_init;
|
||
chgbox_led[i].max_duty = SOFT_MC_PWM_MAX * BRIGHTNESS_MAX / 100;
|
||
chgbox_led[i].mode = GHGBOX_LED_MODE_OFF;
|
||
} else if (i == CHG_LED_GREEN) {
|
||
chgbox_led[i].led_on_off = chg_set_green_led;
|
||
chgbox_led[i].led_init = chg_green_led_init;
|
||
chgbox_led[i].max_duty = SOFT_MC_PWM_MAX * BRIGHTNESS_MAX / 100;
|
||
chgbox_led[i].mode = GHGBOX_LED_MODE_OFF;
|
||
} else if (i == CHG_LED_BLUE) {
|
||
chgbox_led[i].led_on_off = chg_set_blue_led;
|
||
chgbox_led[i].led_init = chg_blue_led_init;
|
||
chgbox_led[i].max_duty = SOFT_MC_PWM_MAX * BRIGHTNESS_MAX / 100;
|
||
chgbox_led[i].mode = GHGBOX_LED_MODE_OFF;
|
||
}
|
||
chgbox_led[i].led_init();
|
||
}
|
||
mc_clk_init();
|
||
}
|
||
|
||
#endif
|
||
|
||
#endif
|