KT24-1110_65E-HA-651B/apps/common/charge_box/chgbox_ui_drv_timer.c
2024-11-10 18:44:17 +08:00

756 lines
26 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 "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