KT24-1110_65E-HA-651B/cpu/br25/pwm_led.c
2024-11-10 18:44:17 +08:00

1827 lines
59 KiB
C

#include "generic/gpio.h"
#include "asm/includes.h"
#include "asm/pwm_led.h"
#include "system/timer.h"
#include "board_config.h"
/*******************************************************************
* 推灯注意事项:
* 1)PWM_CON1的BIT(4), OUT_LOGIC位一定要设置为1;
* 2)PWM_CON1的BIT(0), PWM0_INV位一定要设置为0;
* 3)在非呼吸灯效果下, 单IO双LED模式, PWM_PRD_DIV寄存器和PWM_BRI_PRD设置成相同值;
* 4)在闪灯模式下, PWM_BRI_PRD(亮度值)固定下来后, PWM0的BRI_DUTY0和BRI_DUTY1一定不能超过PWM_BRI_PRD;
*********************************************************************/
/* #ifdef SUPPORT_MS_EXTENSIONS */
/* #pragma bss_seg( ".pwm_led_bss") */
/* #pragma data_seg( ".pwm_led_data") */
/* #pragma const_seg( ".pwm_led_const") */
/* #pragma code_seg( ".pwm_led_code") */
/* #endif */
//#define PWM_LED_TEST_MODE //LED模块测试函数
//#define PWM_LED_DEBUG_ENABLE
#ifdef PWM_LED_DEBUG_ENABLE
#define led_debug(fmt, ...) printf("[PWM_LED] "fmt, ##__VA_ARGS__)
#define led_err(fmt, ...) printf("[PWM_LED_ERR] "fmt, ##__VA_ARGS__)
#else
#define led_debug(...)
#define led_err(...)
#endif
//////////////////////////////////////////////////////////////
#define PWM_LED_SFR SFR
//========================= 0.模块开关相关寄存器
#define LED_PWM_ENABLE (JL_PLED->CON0 |= BIT(0))
#define LED_PWM_DISABLE (JL_PLED->CON0 &= ~BIT(0))
#define IS_PWM_LED_ON (JL_PLED->CON0 & BIT(0))
#define RESET_PWM_CON0 (JL_PLED->CON0 = 0)
#define RESET_PWM_CON1 (JL_PLED->CON1 = 0)
#define RESET_PWM_CON2 (JL_PLED->CON2 = 0)
#define RESET_PWM_CON3 (JL_PLED->CON3 = 0)
//========================= 1.时钟设置相关寄存器
//PWM0 CLK DIV
#define CLK_DIV_1 0
#define CLK_DIV_4 1
#define CLK_DIV_16 2
#define CLK_DIV_64 3
#define CLK_DIV_x2(x) (0x04 | x)
#define CLK_DIV_x256(x) (0x08 | x)
#define CLK_DIV_x2_x256(x) (0x0c | x)
//SOURCE
//0:rclk(250kHz) 1:btosc(24MHz) 2:osc32k(32kHz) 3:rc32k(32kHz)
#define LED_PWM0_CLK_SEL(x) PWM_LED_SFR(JL_PLED->CON0, 2, 2, x)
//SOURCE -- DIV --> PWM0
//[1:0] 00:div1 01:div4 10:div16 11:div64
//[2]: 0:x1 1:x2
//[3]: 0:x1 1:x256
//DIV = [1:0] * [2] * [3]
#define LED_PWM0_CLK_DIV(x) PWM_LED_SFR(JL_PLED->CON0, 4, 4, x)
//PWM0 -- DIV --> PWM1
//PWM_CON3[3:0] -- PWM_PRD_DIVL[7:0] //12bit
#define LED_PWM1_CLK_DIV(x) {do {JL_PLED->PRD_DIVL = ((x-1) & 0xFF); JL_PLED->CON3 &= ~(0xF); JL_PLED->CON3 |= (((x-1) >> 8) & 0xF);} while(0);}
//========================= 2.亮度设置相关寄存器
//最高亮度级数设置
//PWM_BRI_PRDH[1:0] -- PWM_BRI_PRDL[7:0] //10bit
#define LED_BRI_DUTY_CYCLE(x) {do {JL_PLED->BRI_PRDL = (x & 0xFF); JL_PLED->BRI_PRDH = ((x >> 8) & 0x3);} while(0);}
//高电平亮灯亮度设置
#define LED_BRI_DUTY1_SET(x) {do {JL_PLED->BRI_DUTY0L = (x & 0xFF); JL_PLED->BRI_DUTY0H = ((x >> 8) & 0x3);} while(0);}
//低电平亮灯亮度设置
#define LED_BRI_DUTY0_SET(x) {do {JL_PLED->BRI_DUTY1L = (x & 0xFF); JL_PLED->BRI_DUTY1H = ((x >> 8) & 0x3);} while(0);}
//同步LED0 <-- LED1亮度
#define LED_BRI_DUTY0_SYNC1() {do {JL_PLED->BRI_DUTY0L = JL_PLED->BRI_DUTY1L; JL_PLED->BRI_DUTY0H = JL_PLED->BRI_DUTY1H;} while(0);}
//同步LED1 <-- LED0亮度
#define LED_BRI_DUTY1_SYNC0() {do {JL_PLED->BRI_DUTY1L = JL_PLED->BRI_DUTY0L; JL_PLED->BRI_DUTY1H = JL_PLED->BRI_DUTY0H;} while(0);}
//========================= 3.亮灭设置相关寄存器
//duty_cycle 固定为255或者设置PWM_DUTY3, 8bit
// _duty1_ _duty3_
// | | | |
// | | | |
//0__ __ duty0| | __ duty2| |__ __255/PWM_DUTY3
//PWM1 duty_cycle 选择
#define LED_PWM1_DUTY_FIX_SET (JL_PLED->CON1 &= ~BIT(3)) //固定PWM1周期为0xFF
#define LED_PWM1_DUTY_VARY_SET(x) {do {JL_PLED->CON1 |= BIT(3); JL_PLED->DUTY3 = x;} while(0);}
#define LED_PWM1_DUTY0_SET(x) (JL_PLED->DUTY0 = x)
#define LED_PWM1_DUTY1_SET(x) (JL_PLED->DUTY1 = x)
#define LED_PWM1_DUTY2_SET(x) (JL_PLED->DUTY2 = x)
#define LED_PWM1_DUTY3_SET(x) (JL_PLED->DUTY3 = x) //可以设置为PWM1_DUTY_CYCLE
#define LED_PWM1_PRD_SEL_DIS (JL_PLED->CON1 &= ~BIT(3))
#define LED_PWM1_PRD_SEL_EN (JL_PLED->CON1 |= BIT(3))
#define LED_PWM1_DUTY0_EN (JL_PLED->CON1 |= BIT(4))
#define LED_PWM1_DUTY1_EN (JL_PLED->CON1 |= BIT(5))
#define LED_PWM1_DUTY2_EN (JL_PLED->CON1 |= BIT(6))
#define LED_PWM1_DUTY3_EN (JL_PLED->CON1 |= BIT(7))
#define LED_PWM1_ALL_DUTY_DIS (JL_PLED->CON1 &= ~(0xF << 4))
#define LED_PWM1_DUTY0_DIS (JL_PLED->CON1 &= ~BIT(4))
#define LED_PWM1_DUTY1_DIS (JL_PLED->CON1 &= ~BIT(5))
#define LED_PWM1_DUTY2_DIS (JL_PLED->CON1 &= ~BIT(6))
#define LED_PWM1_DUTY3_DIS (JL_PLED->CON1 &= ~BIT(7))
//========================= 5.输出取反相关寄存器
//以下几个需要设置为固定值
#define LED_PWM0_INV_DISABLE (JL_PLED->CON1 &= ~BIT(0))
#define LED_PWM1_INV_DISABLE (JL_PLED->CON1 &= ~BIT(1)) //周期从灭灯开始
#define LED_PWM1_INV_ENABLE (JL_PLED->CON1 |= BIT(1)) //周期从亮灯开始
#define LED_PWM_OUT_LOGIC_SET (JL_PLED->CON3 |= BIT(4))
//以下几个可以灵活设置
#define LED_PWM_OUTPUT_INV_ENABLE (JL_PLED->CON1 |= BIT(2))
#define LED_PWM_OUTPUT_INV_DISABLE (JL_PLED->CON1 &= ~BIT(2))
//========================= 6.与周期变色相关寄存器
#define LED_PWM_SHIFT_DUTY_SET(x) PWM_LED_SFR(JL_PLED->CON2, 4, 4, x)
//========================= 7.与驱动强度相关寄存器
#define LED_PWM_IO_MAX_DRIVE(x) PWM_LED_SFR(JL_PLED->CON2, 0, 2, x)
//========================= 8.与中断相关寄存器
#define LED_PWM_INT_EN (JL_PLED->CON3 |= BIT(5))
#define LED_PWM_INT_DIS (JL_PLED->CON3 &= ~BIT(5))
#define LED_PWM_CLR_PENDING (JL_PLED->CON3 |= BIT(6))
//========================= 9.与呼吸模式相关寄存器
#define LED_PWM_BREATHE_ENABLE (JL_PLED->CON0 |= BIT(1))
#define LED_PWM_BREATHE_DISABLE (JL_PLED->CON0 &= ~BIT(1))
//LED呼吸灭灯延时设置, 16bit
#define LED_PWM_BREATHE_BLANK_TIME_SET(x) {do {LED_PWM1_DUTY2_EN; LED_PWM1_DUTY3_EN; LED_PWM1_DUTY2_SET((x & 0xFF)); LED_PWM1_DUTY3_SET((x >> 8) & 0xFF)} while(0)}
//LED呼吸灯(低电平灯)最高亮度延时设置, 8bit
#define LED0_PWM_BREATHE_LIGHT_TIME_SET(x) {do {LED_PWM1_DUTY0_EN; LED_PWM1_DUTY0_SET(x)} while(0)}
//LED呼吸灯(高电平灯)最高亮度延时设置, 8bit
#define LED1_PWM_BREATHE_LIGHT_TIME_SET(x) {do {LED_PWM1_DUTY1_EN; LED_PWM1_DUTY1_SET(x)} while(0)}
struct pwm_led {
u8 init;
u8 led_pin;
u8 clock;
u8 last_mode;
const struct led_platform_data *user_data;
//中断相关
void (*pwm_led_extern_isr)(void);
void (*pwm_led_local_isr)(void);
#ifdef PWM_LED_TWO_IO_SUPPORT
u8 display_index;
#endif /* #ifdef PWM_LED_TWO_IO_SUPPORT */
};
typedef struct {
pwm_led_on_para on;
pwm_led_one_flash_para one_flash;
pwm_led_double_flash_para double_flash;
pwm_led_breathe_para breathe;
} pwm_led_para_t;
static pwm_led_para_t led_para;
enum _PWM0_CLK {
PWM0_CLK_32K, //for rc normal
//BT24M
PWM0_CLK_46K, //24M / 512 = 46875, for normal period < 22s
PWM0_CLK_23K, //24M / 1024 = 23437, for normal period > 22s
};
#define PWM0_RC_CLK32K_VALUE 32000
#define PWM0_BT_CLK23K_VALUE 23437
#define PWM0_BT_CLK46K_VALUE 46875
#define PWM_LED_USER_DEFINE_MODE 0xFE
static struct pwm_led _led;
#define __this (&_led)
#define P3_CLK_CON0 0xa6
extern void p33_tx_1byte(u16 addr, u8 data0);
extern u8 p33_rx_1byte(u16 addr);
extern void set_timer_pwm_duty(JL_TIMER_TypeDef *JL_TIMERx, u32 duty);
static void _pwm_led_display_mode(u8 display);
static void _led_pwm1_duty_set(u8 duty_prd, u8 duty0, u8 duty1, u8 duty2, u8 breathe);
static void pwm_clock_set(u8 _clock)
{
u8 clock = _clock;
u8 clk_val = 0;
switch (clock) {
case PWM_LED_CLK_RC32K:
clk_val = 1;
break;
case PWM_LED_CLK_BTOSC_24M:
clk_val = 2;
break;
default:
break;
}
P33_CON_SET(P3_CLK_CON0, 0, 2, clk_val);
/* p33_tx_1byte(P3_CLK_CON0, clk_val); */
__this->clock = clock;
led_debug("clock = 0x%x, clk_val= %d, P3_CLK_CON0 = 0x%x", __this->clock, clk_val, p33_rx_1byte(P3_CLK_CON0));
}
/*
* IO使能注意, 否则有可能会出现在显示效果前会出现闪烁
* 1)设置PU, PD为1;
* 2)设置DIR, OUT为1;
* 3)最后设置为方向为输出;
*/
void led_pin_set_enable(u8 gpio)
{
gpio_set_pull_up(gpio, 1);
gpio_set_pull_down(gpio, 1);
gpio_set_die(gpio, 1);
gpio_set_output_value(gpio, 1);
gpio_set_direction(gpio, 0);
}
//把IO设置为高阻
void led_pin_set_disable(u8 disable_pin)
{
gpio_set_pull_down(disable_pin, 0);
gpio_set_pull_up(disable_pin, 0);
gpio_direction_input(disable_pin);
}
___interrupt
static void pwm_led_isr_func(void)
{
LED_PWM_CLR_PENDING;
led_debug("led isr");
if (__this->pwm_led_extern_isr) {
__this->pwm_led_extern_isr();
}
if (__this->pwm_led_local_isr) {
__this->pwm_led_local_isr();
}
}
//index = 0: 内部切IO中断;
//index = 1: 外部注册中断;
static void _pwm_led_register_irq(void (*func)(void), u8 index)
{
LED_PWM_INT_DIS;
LED_PWM_CLR_PENDING;
if (func) {
if (index) {
__this->pwm_led_local_isr = func;
} else {
__this->pwm_led_extern_isr = func;
}
request_irq(IRQ_PWM_LED_IDX, 1, pwm_led_isr_func, 0);
LED_PWM_INT_EN;
}
}
static void _pwm_led_close_irq(void)
{
__this->pwm_led_extern_isr = NULL;
__this->pwm_led_local_isr = NULL;
LED_PWM_INT_DIS;
}
void pwm_led_init(const struct led_platform_data *user_data)
{
led_debug("pwm led init ...");
memset(__this, 0, sizeof(struct pwm_led));
LED_PWM_DISABLE;
LED_PWM_BREATHE_DISABLE; //呼吸灯使能位
RESET_PWM_CON0;
RESET_PWM_CON1;
RESET_PWM_CON2;
RESET_PWM_CON3;
LED_PWM_OUT_LOGIC_SET;
LED_PWM_CLR_PENDING;
#if(defined(TCFG_LOWPOWER_OSC_TYPE) && TCFG_LOWPOWER_OSC_TYPE == OSC_TYPE_LRC)
pwm_clock_set(PWM_LED_CLK_RC32K);
#else
pwm_clock_set(PWM_LED_CLK_BTOSC_24M);
#endif
if (user_data->io_mode == LED_ONE_IO_MODE) {
__this->led_pin = user_data->io_cfg.one_io.pin;
led_pin_set_enable(user_data->io_cfg.one_io.pin); //一个IO推两个灯
}
__this->user_data = user_data;
__this->last_mode = PWM_LED_ALL_OFF;
__this->init = 1;
}
void log_pwm_led_info()
{
led_debug("======== PWM LED CONFIG ======");
led_debug("P3_CLK_CON0 = 0x%x", p33_rx_1byte(P3_CLK_CON0));
led_debug("PWM_CON0 = 0x%x", JL_PLED->CON0);
led_debug("PWM_CON1 = 0x%x", JL_PLED->CON1);
led_debug("PWM_CON2 = 0x%x", JL_PLED->CON2);
led_debug("PWM_CON3 = 0x%x", JL_PLED->CON3);
led_debug("PRD_DIVL = 0x%x", JL_PLED->PRD_DIVL);
led_debug("BRI_PRDL = 0x%x", JL_PLED->BRI_PRDL);
led_debug("BRI_PRDH = 0x%x", JL_PLED->BRI_PRDH);
led_debug("BRI_DUTY0L = 0x%x", JL_PLED->BRI_DUTY0L);
led_debug("BRI_DUTY0H = 0x%x", JL_PLED->BRI_DUTY0H);
led_debug("BRI_DUTY1L = 0x%x", JL_PLED->BRI_DUTY1L);
led_debug("BRI_DUTY1H = 0x%x", JL_PLED->BRI_DUTY1H);
led_debug("PWM1_DUTY0 = 0x%x", JL_PLED->DUTY0);
led_debug("PWM1_DUTY1 = 0x%x", JL_PLED->DUTY1);
led_debug("PWM1_DUTY2 = 0x%x", JL_PLED->DUTY2);
led_debug("PWM1_DUTY3 = 0x%x", JL_PLED->DUTY3);
}
/**
* @brief: pwm0 时钟设置
* 默认RC = 32K,
* 呼吸BT24M = 93750Hz
* 普通BT24M = 46875Hz/23437Hz
*
* @param: clk0
* @return int
*/
static int _led_pwm0_clk_set(enum _PWM0_CLK clk0)
{
u8 pwm0_clk_div_val = 0;
if (__this->clock == PWM_LED_CLK_RC32K) {
if (clk0 != PWM0_CLK_32K) {
return -1;
}
pwm0_clk_div_val = CLK_DIV_1; //RC32k div 1 = 32k
} else {
#if CONFIG_FPGA_ENABLE
//12M
if (clk0 == PWM0_CLK_46K) {
pwm0_clk_div_val = CLK_DIV_x256(CLK_DIV_1); //12M div 256 = 46875Hz
} else if (clk0 == PWM0_CLK_23K) {
pwm0_clk_div_val = CLK_DIV_x256(CLK_DIV_x2(CLK_DIV_1)); //12M div 512 = 23437Hz
} else {
return -1;
}
#else
if (clk0 == PWM0_CLK_46K) {
pwm0_clk_div_val = CLK_DIV_x256(CLK_DIV_x2(CLK_DIV_1)); //24M div 512 = 46875Hz
} else if (clk0 == PWM0_CLK_23K) {
pwm0_clk_div_val = CLK_DIV_x256(CLK_DIV_4); //24M div 1024 = 23437Hz
} else {
return -1;
}
#endif /* #if CONFIG_FPGA_ENABLE */
}
LED_PWM0_CLK_DIV(pwm0_clk_div_val);
return 0;
}
static void led_pwm_pre_set()
{
LED_PWM_DISABLE;
LED_PWM_BREATHE_DISABLE;
}
#ifdef PWM_LED_TWO_IO_SUPPORT
static void _change_io_display(void)
{
u8 disable_pin = 0;
u8 enable_pin = 0;
if (__this->display_index == 0) {
enable_pin = __this->user_data->io_cfg.two_io.pin1;
disable_pin = __this->user_data->io_cfg.two_io.pin0;
__this->display_index = 1;
} else {
enable_pin = __this->user_data->io_cfg.two_io.pin0;
disable_pin = __this->user_data->io_cfg.two_io.pin1;
__this->display_index = 0;
}
led_pin_set_disable(disable_pin);
led_pin_set_enable(enable_pin);
}
static void pwm_led_two_io_mode_display(u8 display)
{
u8 change_mode = 0;
u8 isr_mode = 0;
led_pin_set_disable(__this->user_data->io_cfg.two_io.pin0);
led_pin_set_disable(__this->user_data->io_cfg.two_io.pin1);
#if (PWM_LED_TWO_IO_CONNECT == 0)
switch (display) {
case PWM_LED_ALL_OFF:
case PWM_LED0_OFF:
case PWM_LED1_OFF:
_pwm_led_display_mode(PWM_LED_ALL_OFF);
break;
case PWM_LED1_ON:
case PWM_LED1_SLOW_FLASH:
case PWM_LED1_FAST_FLASH:
case PWM_LED1_ONE_FLASH_5S:
case PWM_LED1_DOUBLE_FLASH_5S:
case PWM_LED1_BREATHE:
led_pin_set_enable(__this->user_data->io_cfg.two_io.pin1);
_pwm_led_display_mode(display);
break;
case PWM_LED0_ON:
change_mode = PWM_LED1_ON;
break;
case PWM_LED0_SLOW_FLASH:
change_mode = PWM_LED1_SLOW_FLASH;
break;
case PWM_LED0_FAST_FLASH:
change_mode = PWM_LED1_FAST_FLASH;
break;
case PWM_LED0_ONE_FLASH_5S:
change_mode = PWM_LED1_ONE_FLASH_5S;
break;
case PWM_LED0_DOUBLE_FLASH_5S:
change_mode = PWM_LED1_DOUBLE_FLASH_5S;
break;
case PWM_LED0_BREATHE:
change_mode = PWM_LED1_BREATHE;
break;
case PWM_LED_ALL_ON:
_pwm_led_display_mode(PWM_LED1_ON);
led_pin_set_enable(__this->user_data->io_cfg.two_io.pin0);
led_pin_set_enable(__this->user_data->io_cfg.two_io.pin1);
break;
/////////////
//双灯互闪
case PWM_LED0_LED1_FAST_FLASH: //使用中断切灯
isr_mode = PWM_LED1_FAST_FLASH;
break;
case PWM_LED0_LED1_SLOW_FLASH:
isr_mode = PWM_LED1_SLOW_FLASH;
break;
//呼吸模式
case PWM_LED0_LED1_BREATHE: //使用中断切灯
isr_mode = PWM_LED1_BREATHE;
break;
default:
break;
}
if (change_mode) {
_pwm_led_display_mode(change_mode);
LED_PWM_DISABLE;
LED_BRI_DUTY1_SYNC0();
led_pin_set_enable(__this->user_data->io_cfg.two_io.pin0);
LED_PWM_ENABLE;
}
if (isr_mode) {
_pwm_led_display_mode(isr_mode);
_led_pwm1_duty_set(0xFF, 2, 0, 0, 0); //占满整个周期
_pwm_led_register_irq(_change_io_display, 0);
led_pin_set_enable(__this->user_data->io_cfg.two_io.pin0);
__this->display_index = 0;
}
#else
switch (display) {
case PWM_LED_ALL_OFF:
case PWM_LED0_OFF:
case PWM_LED1_OFF:
_pwm_led_display_mode(PWM_LED_ALL_OFF);
break;
case PWM_LED0_ON:
case PWM_LED0_SLOW_FLASH:
case PWM_LED0_FAST_FLASH:
case PWM_LED0_ONE_FLASH_5S:
case PWM_LED0_DOUBLE_FLASH_5S:
case PWM_LED0_BREATHE:
led_pin_set_enable(__this->user_data->io_cfg.two_io.pin0);
_pwm_led_display_mode(display);
break;
case PWM_LED1_ON:
change_mode = PWM_LED0_ON;
break;
case PWM_LED1_SLOW_FLASH:
change_mode = PWM_LED0_SLOW_FLASH;
break;
case PWM_LED1_FAST_FLASH:
change_mode = PWM_LED0_FAST_FLASH;
break;
case PWM_LED1_ONE_FLASH_5S:
change_mode = PWM_LED0_ONE_FLASH_5S;
break;
case PWM_LED1_DOUBLE_FLASH_5S:
change_mode = PWM_LED0_DOUBLE_FLASH_5S;
break;
case PWM_LED1_BREATHE:
change_mode = PWM_LED0_BREATHE;
break;
case PWM_LED_ALL_ON:
_pwm_led_display_mode(PWM_LED0_ON);
led_pin_set_enable(__this->user_data->io_cfg.two_io.pin0);
led_pin_set_enable(__this->user_data->io_cfg.two_io.pin1);
break;
/////////////
//双灯互闪
case PWM_LED0_LED1_FAST_FLASH: //使用中断切灯
isr_mode = PWM_LED0_FAST_FLASH;
break;
case PWM_LED0_LED1_SLOW_FLASH:
isr_mode = PWM_LED0_SLOW_FLASH;
break;
//呼吸模式
case PWM_LED0_LED1_BREATHE: //使用中断切灯
isr_mode = PWM_LED0_BREATHE;
break;
default:
break;
}
if (change_mode) {
_pwm_led_display_mode(change_mode);
LED_PWM_DISABLE;
LED_BRI_DUTY0_SYNC1();
led_pin_set_enable(__this->user_data->io_cfg.two_io.pin1);
LED_PWM_ENABLE;
}
if (isr_mode) {
_pwm_led_display_mode(isr_mode);
_led_pwm1_duty_set(0xFF, 2, 0, 0, 0); //占满整个周期
_pwm_led_register_irq(_change_io_display, 0);
led_pin_set_enable(__this->user_data->io_cfg.two_io.pin0);
__this->display_index = 0;
}
#endif
}
static void _pwm_led_two_io_user_define_mode(u8 led_index)
{
led_pwm_pre_set(); //led disable
led_pin_set_disable(__this->user_data->io_cfg.two_io.pin0);
led_pin_set_disable(__this->user_data->io_cfg.two_io.pin1);
if (led_index == 0) {
led_pin_set_enable(__this->user_data->io_cfg.two_io.pin0);
} else if (led_index == 1) {
led_pin_set_enable(__this->user_data->io_cfg.two_io.pin1);
} else if (led_index == 2) {
//双灯互闪切换
__this->display_index = 0;
led_pin_set_enable(__this->user_data->io_cfg.two_io.pin0);
_pwm_led_register_irq(_change_io_display, 0);
}
}
#else
static void pwm_led_two_io_mode_display(u8 display)
{
return;
}
#endif /* #ifdef PWM_LED_TWO_IO_SUPPORT */
static void pwm_led_one_io_mode_display(u8 display)
{
_pwm_led_display_mode(display);
}
/////////////////////////////
/**
* @brief: 设置led灯亮度
* @param: bri_max, 最大亮度, 10bit, 0 ~ 1023
* @param: bri_duty0, LED0亮度, 10bit, 0 ~ 1023
* @param: bri_duty1, LED1亮度, 10bit, 0 ~ 1023
*
* @return void
*/
static void _led_pwm_bright_set(u16 bri_max, u16 bri_duty0, u16 bri_duty1)
{
bri_max = bri_max >= 1024 ? 1023 : bri_max;
bri_duty0 = bri_duty0 >= 1024 ? 1023 : bri_duty0;
bri_duty1 = bri_duty1 >= 1024 ? 1023 : bri_duty1;
bri_duty0 = bri_duty0 >= bri_max ? bri_max : bri_duty0;
bri_duty1 = bri_duty1 >= bri_max ? bri_max : bri_duty1;
LED_BRI_DUTY_CYCLE(bri_max);
LED_BRI_DUTY0_SET(bri_duty0);
LED_BRI_DUTY1_SET(bri_duty1);
}
void set_led_duty(u16 duty)
{
#if defined(CONFIG_CPU_BR23)
set_timer_pwm_duty(JL_TIMER3, duty);
#elif defined(CONFIG_CPU_BR25)
set_timer_pwm_duty(JL_TIMER5, duty);
#elif defined(CONFIG_CPU_BR30)
set_timer_pwm_duty(JL_TIMER5, duty);
#endif
}
/**
* @brief: 设置PWM输出逻辑,
* @param: pwm_inv_en, 最后pwm波形输出逻辑(默认是高电平灯亮),
0: 不取反, 高电平灯亮; 1: 取反, 低电平灯亮;
* @param: shift_num
是否需要互闪,
0: 单闪; 1 ~ : 互闪;
*
* @return void
*/
static void _led_pwm_output_logic_set(u8 pwm_inv_en, u8 shift_num)
{
if (pwm_inv_en) {
LED_PWM_OUTPUT_INV_ENABLE;
} else {
LED_PWM_OUTPUT_INV_DISABLE;
}
LED_PWM_OUT_LOGIC_SET;
LED_PWM_SHIFT_DUTY_SET(shift_num);
}
/**
* @brief: 设置PWM1亮灭设置, 可以实现一个周期亮灭1次和2次,
* @param: pwm_inv_en, 最后pwm波形输出逻辑(默认是高电平灯亮),
0: 不取反, 高电平灯亮; 1: 取反, 低电平灯亮;
* @param: shift_num
是否需要互闪,
0: 单闪; 1 ~ : 互闪;
*duty_cycle 固定为255或者设置PWM_DUTY3, 8bit
* _duty1_ _duty3_
* | | | |
* | | | |
*0__ __ duty0| | __ duty2| |__ __255/PWM_DUTY3
* @return void
*/
static void _led_pwm1_duty_set(u8 duty_prd, u8 duty0, u8 duty1, u8 duty2, u8 breathe)
{
if (duty_prd != 0xFF) {
if (breathe == 0) {
duty0 = duty0 > duty_prd ? duty_prd : duty0;
duty1 = duty1 > duty_prd ? duty_prd : duty1;
duty2 = duty2 > duty_prd ? duty_prd : duty2;
LED_PWM1_PRD_SEL_EN;
LED_PWM1_DUTY3_DIS;
} else {
LED_PWM1_PRD_SEL_DIS; //呼吸模式, duty0/1是亮灯延时, {duty3,duty2}是灭灯延时
LED_PWM1_DUTY3_EN;
}
LED_PWM1_DUTY3_SET(duty_prd);
} else {
LED_PWM1_PRD_SEL_DIS;
LED_PWM1_DUTY3_DIS;
}
if (duty0) {
LED_PWM1_DUTY0_SET(duty0);
LED_PWM1_DUTY0_EN;
} else {
LED_PWM1_DUTY0_DIS;
}
if (duty1) {
LED_PWM1_DUTY1_SET(duty1);
LED_PWM1_DUTY1_EN;
} else {
LED_PWM1_DUTY1_DIS;
}
if (duty2) {
LED_PWM1_DUTY2_SET(duty2);
LED_PWM1_DUTY2_EN;
} else {
LED_PWM1_DUTY2_DIS;
}
}
/**
* @brief:
* @param: module_en = 0, breathe_en = 0, 关LED模块
* @param: module_en = 0, breathe_en = 1, 关LED模块
* @param: module_en = 1, breathe_en = 0, 开LED普通闪烁模式
* @param: module_en = 1, breathe_en = 1, 开LED呼吸模式
* @return void
*/
static void _led_pwm_module_enable(u8 module_en, u8 breathe_en)
{
if (breathe_en) {
LED_PWM_BREATHE_ENABLE;
} else {
LED_PWM_BREATHE_DISABLE;
}
if (module_en) {
LED_PWM_ENABLE;
} else {
LED_PWM_DISABLE;
}
}
/**
* @brief: 设置pwm0时钟分频
* clk0_div
* pwm0_clk --------> pwm1_clk
* @param: clk0_div, 12bit, 0 ~ 4095
*
* @return void
*/
static void _led_pwm1_clk_set(u16 clk0_div)
{
clk0_div = clk0_div > 4096 ? 4096 : clk0_div;
LED_PWM1_CLK_DIV(clk0_div);
}
/**
* @brief: 关 led 配置, 亮度也设置为0
*
* @param led_index: 0: led0, 1:led1, 3:led0 & led1
* @param led0_bright: 0 ~ 100
* @param led1_bright: 0 ~ 100
*
* @return void
*/
static void _pwm_led_off_display(void)
{
//TODO: set bright duty 0: avoid set on case
led_pwm_pre_set(); //led disable
_led_pwm_bright_set(0xFF, 0, 0);
}
/**
* @brief: led 常亮显示设置
* @param led_index: 0: led0, 1:led1, 3:led0 & led1
* @param led0_bright, LED0亮度: 0 ~ 500
* @param led1_bright, LED1亮度: 0 ~ 500
*
* @return void
*/
void _pwm_led_on_display(u8 led_index, u16 led0_bright, u16 led1_bright)
{
//step1: pwm0 clock
if (__this->clock == PWM_LED_CLK_RC32K) {
_led_pwm0_clk_set(PWM0_CLK_32K);
} else {
_led_pwm0_clk_set(PWM0_CLK_46K);
}
//step2: pwm1 clock
_led_pwm1_clk_set(4);
//bright set
u8 shift_num = 0;
u8 out_inv = 0;
u16 led0_bri_duty = 0;
u16 led1_bri_duty = 0;
u16 led_bri_prd = 200;
led0_bri_duty = led0_bright;
led1_bri_duty = led1_bright;
switch (led_index) {
case 0:
out_inv = 1;
break;
case 1:
break;
case 2:
shift_num = 1;
led_bri_prd = 160;
break;
default:
led_debug("%s led index err", __func__);
return;
break;
}
led0_bri_duty = (led0_bri_duty * led_bri_prd) / 500;
led1_bri_duty = (led1_bri_duty * led_bri_prd) / 500; //调试数据
//step3: bright亮度
_led_pwm_bright_set(led_bri_prd, led0_bri_duty, led1_bri_duty);
//step4: 1.输出取反, 2.变色(互闪);
_led_pwm_output_logic_set(out_inv, shift_num);
//step5: 周期亮灭配置
//pwm1 duty0, duty1, duty2
_led_pwm1_duty_set(40, 2, 0, 0, 0);
//step6: enable led module
_led_pwm_module_enable(1, 0);
}
static void __pwm_led_flash_common_handle(u8 led_index, u16 led0_bright, u16 led1_bright, u32 period)
{
//step1: pwm0 clock
u16 pwm0_prd = 500;
u16 pwm0_div = 0;
if (__this->clock == PWM_LED_CLK_RC32K) {
_led_pwm0_clk_set(PWM0_CLK_32K);
pwm0_div = (PWM0_RC_CLK32K_VALUE * period) / (1000 * 256);
} else {
if (period < 22000) {
_led_pwm0_clk_set(PWM0_CLK_46K);
pwm0_div = (PWM0_BT_CLK46K_VALUE * period) / (1000 * 256);
} else {
_led_pwm0_clk_set(PWM0_CLK_23K);
pwm0_div = (PWM0_BT_CLK23K_VALUE * period) / (1000 * 256);
pwm0_prd = 300;
led0_bright = (led0_bright * 300) / 500;
led1_bright = (led1_bright * 300) / 500;
}
}
//step2: pwm1 clock
_led_pwm1_clk_set(pwm0_div);
//bright set
u8 shift_num = 0;
u8 out_inv = 0;
u16 led0_bri_duty = 0;
u16 led1_bri_duty = 0;
switch (led_index) {
case 0:
led0_bri_duty = led0_bright;
led1_bri_duty = 0;
out_inv = 1;
break;
case 1:
led0_bri_duty = 0;
led1_bri_duty = led1_bright;
break;
case 2:
shift_num = 1;
led0_bri_duty = led0_bright;
led1_bri_duty = led1_bright;
break;
default:
led_debug("%s led index err", __func__);
return;
break;
}
//step3: bright亮度
_led_pwm_bright_set(pwm0_prd, led0_bri_duty, led1_bri_duty);
//step4: 1.输出取反, 2.变色(互闪);
_led_pwm_output_logic_set(out_inv, shift_num);
}
/**
* @brief: led 周期闪一次显示设置
* @param led_index: 0: led0, 1:led1, 3:led0 & led1(互闪)
led0_bright: led0亮度(0 ~ 500),
led1_bright: led1亮度(0 ~ 500),
period: 闪灯周期(ms), 多少ms闪一下(100 ~ 20000), 100ms - 20S,
start_light_time: 在周期中开始亮灯的时间, -1: 周期最后亮灯, 默认填-1即可,
light_time: 灯亮持续时间,
*
* @return void
*/
static void _pwm_led_one_flash_display(u8 led_index, u16 led0_bright, u16 led1_bright,
u32 period, u32 start_light_time, u32 light_time)
{
__pwm_led_flash_common_handle(led_index, led0_bright, led1_bright, period);
//step5: 周期亮灭配置
//pwm1 duty0, duty1, duty2
u8 pwm1_duty0 = 0;
u8 pwm1_duty1 = 0;
if (start_light_time != -1) {
if (start_light_time >= period) {
led_err("start_light_time config err");
_pwm_led_off_display(); //led off
return;
}
//指定从哪个时间亮,
pwm1_duty0 = (256 * start_light_time) / period;
pwm1_duty0 = (pwm1_duty0) ? pwm1_duty0 : 2;
if ((start_light_time + light_time) > period) {
pwm1_duty1 = 0; //只开duty0
} else {
pwm1_duty1 = (256 * light_time) / period;
pwm1_duty1 = (pwm1_duty1) ? pwm1_duty1 : 2;
if ((pwm1_duty0 + pwm1_duty1) > 0xFF) {
pwm1_duty1 = 0 ;
} else {
pwm1_duty1 += pwm1_duty0;
}
}
} else {
pwm1_duty0 = (256 * light_time) / period;
pwm1_duty0 = (pwm1_duty0) ? pwm1_duty0 : 2;
pwm1_duty0 = 256 - pwm1_duty0;
}
if ((led_index == 2) && (light_time == -1)) { //互闪, 占满整个周期
pwm1_duty0 = 2;
pwm1_duty1 = 0;
}
_led_pwm1_duty_set(0xFF, pwm1_duty0, pwm1_duty1, 0, 0);
//step6: enable led module
_led_pwm_module_enable(1, 0);
}
/**
* @brief: led 周期闪一次显示设置
* @param led_index: 0: led0, 1:led1, 3:led0 & led1(互闪)
led0_bright: led0亮度,
led1_bright: led1亮度,
period: 闪灯周期(ms), 多少ms闪一下
first_light_time: 第一次亮灯持续时间,
second_light_time: 第二次亮灯持续时间,
gap_time: 两次亮灯时间间隔,
* @param led0_bright, LED0亮度: 0 ~ 500
* @param led1_bright, LED1亮度: 0 ~ 500
*
* @return void
*/
static void _pwm_led_double_flash_display(u8 led_index, u16 led0_bright, u16 led1_bright,
u32 period, u32 first_light_time, u32 gap_time, u32 second_light_time)
{
__pwm_led_flash_common_handle(led_index, led0_bright, led1_bright, period);
//step5: 周期亮灭配置
//pwm1 duty0, duty1, duty2
u8 pwm1_duty0 = 0;
u8 pwm1_duty1 = 0;
u8 pwm1_duty2 = 0;
pwm1_duty2 = (256 * second_light_time) / period;
pwm1_duty2 = (pwm1_duty2) ? (0xFF - pwm1_duty2) : (0xFF - 2);
pwm1_duty1 = (256 * gap_time) / period;
pwm1_duty1 = (pwm1_duty1) ? (pwm1_duty2 - pwm1_duty1) : (pwm1_duty2 - 2);
pwm1_duty0 = (256 * first_light_time) / period;
pwm1_duty0 = (pwm1_duty0) ? (pwm1_duty1 - pwm1_duty0) : (pwm1_duty1 - 2);
_led_pwm1_duty_set(0xFF, pwm1_duty0, pwm1_duty1, pwm1_duty2, 0);
//step6: enable led module
_led_pwm_module_enable(1, 0);
}
/**
* @brief: led 周期呼吸显示,
* @param led_index: 0: led0, 1:led1, 2:led0 & led1(交互呼吸)
breathe_time: 呼吸周期(灭->最亮->灭), 设置范围: 500ms以上;
led0_bright: led0呼吸到最亮的亮度(0 ~ 500);
led1_bright: led1呼吸到最亮的亮度(0 ~ 500);
led0_light_delay_time: led0最高亮度延时(0 ~ 100ms);
led1_light_delay_time: led1最高亮度延时(0 ~ 100ms);
led_blink_delay_time: led0和led1灭灯延时(0 ~ 20000ms), 0 ~ 20S;
*
* @return void
*/
static void _pwm_led_breathe_display(u8 led_index, u16 breathe_time, u16 led0_bright, u16 led1_bright,
u32 led0_light_delay_time, u32 led1_light_delay_time, u32 led_blink_delay_time)
{
u16 led0_bri_duty = led0_bright;
u16 led1_bri_duty = led1_bright;
u16 pwm1_div = 0;
u16 Tpwm1 = 0;
pwm1_div = led0_bri_duty > led1_bri_duty ? led0_bri_duty : led1_bri_duty;
breathe_time = breathe_time / 2; //呼吸总时间, 单个灭到最亮的时间
//step1: pwm0 clock
if (__this->clock == PWM_LED_CLK_RC32K) {
_led_pwm0_clk_set(PWM0_CLK_32K);
pwm1_div = breathe_time * 32 / pwm1_div;
Tpwm1 = (pwm1_div * 1000 / 32000); //ms
} else {
_led_pwm0_clk_set(PWM0_CLK_46K);
pwm1_div = breathe_time * 46 / pwm1_div;
Tpwm1 = (pwm1_div * 1000 / 46000); //ms
}
//step2: pwm1 clock
_led_pwm1_clk_set(pwm1_div);
//bright set
u8 shift_num = 0;
u8 out_inv = 0;
switch (led_index) {
case 0:
led1_bri_duty = 0;
out_inv = 1;
break;
case 1:
led0_bri_duty = 0;
break;
case 2:
shift_num = 2;
break;
default:
led_debug("%s led index err", __func__);
return;
}
//step3: bright亮度
_led_pwm_bright_set(500, led0_bri_duty, led1_bri_duty);
//step4: 1.输出取反, 2.变色(互闪);
_led_pwm_output_logic_set(out_inv, shift_num);
//step5: 周期亮灭配置
//pwm1 duty0, duty1, duty2
u8 pwm1_duty0 = 0;
u8 pwm1_duty1 = 0;
u8 pwm1_duty2 = 0;
u8 pwm1_duty3 = 0xFF;
if (Tpwm1 == 0) {
led0_light_delay_time *= 2;
led1_light_delay_time *= 2;
led_blink_delay_time *= 2;
Tpwm1 = 1;
}
//最高亮度延时
pwm1_duty0 = led0_light_delay_time / Tpwm1;
pwm1_duty1 = led1_light_delay_time / Tpwm1;
//灭灯延时,{duty3, duty2}, 16bit
pwm1_duty2 = (led_blink_delay_time / Tpwm1) & 0xFF;
pwm1_duty3 = ((led_blink_delay_time / Tpwm1) >> 8) & 0xFF;
_led_pwm1_duty_set(pwm1_duty3, pwm1_duty0, pwm1_duty1, pwm1_duty2, 1);
//step6: enable led module
_led_pwm_module_enable(1, 1);
}
static void _pwm_led_display_mode(u8 display)
{
led_pwm_pre_set();
switch (display) {
#if PWM_LED_NEW_FORMAT_EN
case PWM_LED_ALL_OFF:
case PWM_LED0_OFF:
case PWM_LED1_OFF:
_pwm_led_off_display();
break;
//灯常亮
case PWM_LED0_ON:
printf("led0 on:%d %d \n", led_para.on.led0_bright, led_para.on.led1_bright);
_pwm_led_on_display(0, led_para.on.led0_bright, led_para.on.led1_bright);
break;
case PWM_LED1_ON:
printf("led1 on:%d %d \n", led_para.on.led0_bright, led_para.on.led1_bright);
_pwm_led_on_display(1, led_para.on.led0_bright, led_para.on.led1_bright);
break;
case PWM_LED_ALL_ON:
printf("led0_led1 on:%d %d \n", led_para.on.led0_bright, led_para.on.led1_bright);
_pwm_led_on_display(2, led_para.on.led0_bright, led_para.on.led1_bright);
break;
//单灯单闪
case PWM_LED0_SLOW_FLASH:
printf("led0 slow:%d %d %d %d %d \n", led_para.one_flash.led0_bright, led_para.one_flash.led1_bright, \
led_para.one_flash.period, led_para.one_flash.start_light_time, \
led_para.one_flash.light_time);
_pwm_led_one_flash_display(0, \
led_para.one_flash.led0_bright, led_para.one_flash.led1_bright, \
led_para.one_flash.period, led_para.one_flash.start_light_time, \
led_para.one_flash.light_time);
break;
case PWM_LED1_SLOW_FLASH:
printf("led1 slow:%d %d %d %d %d \n", led_para.one_flash.led0_bright, led_para.one_flash.led1_bright, \
led_para.one_flash.period, led_para.one_flash.start_light_time, \
led_para.one_flash.light_time);
_pwm_led_one_flash_display(1, \
led_para.one_flash.led0_bright, led_para.one_flash.led1_bright, \
led_para.one_flash.period, led_para.one_flash.start_light_time, \
led_para.one_flash.light_time);
break;
case PWM_LED0_FAST_FLASH:
printf("led0 fast:%d %d %d %d %d \n", led_para.one_flash.led0_bright, led_para.one_flash.led1_bright, \
led_para.one_flash.period, led_para.one_flash.start_light_time, \
led_para.one_flash.light_time);
_pwm_led_one_flash_display(0, \
led_para.one_flash.led0_bright, led_para.one_flash.led1_bright, \
led_para.one_flash.period, led_para.one_flash.start_light_time, \
led_para.one_flash.light_time);
break;
case PWM_LED1_FAST_FLASH:
printf("led1 fast:%d %d %d %d %d \n", led_para.one_flash.led0_bright, led_para.one_flash.led1_bright, \
led_para.one_flash.period, led_para.one_flash.start_light_time, \
led_para.one_flash.light_time);
_pwm_led_one_flash_display(1, \
led_para.one_flash.led0_bright, led_para.one_flash.led1_bright, \
led_para.one_flash.period, led_para.one_flash.start_light_time, \
led_para.one_flash.light_time);
break;
case PWM_LED0_ONE_FLASH_5S:
printf("led0 one 5s:%d %d %d %d %d \n", led_para.one_flash.led0_bright, led_para.one_flash.led1_bright, \
led_para.one_flash.period, led_para.one_flash.start_light_time, \
led_para.one_flash.light_time);
_pwm_led_one_flash_display(0, \
led_para.one_flash.led0_bright, led_para.one_flash.led1_bright, \
led_para.one_flash.period, led_para.one_flash.start_light_time, \
led_para.one_flash.light_time);
break;
case PWM_LED1_ONE_FLASH_5S:
printf("led1 one 5s:%d %d %d %d %d \n", led_para.one_flash.led0_bright, led_para.one_flash.led1_bright, \
led_para.one_flash.period, led_para.one_flash.start_light_time, \
led_para.one_flash.light_time);
_pwm_led_one_flash_display(1, \
led_para.one_flash.led0_bright, led_para.one_flash.led1_bright, \
led_para.one_flash.period, led_para.one_flash.start_light_time, \
led_para.one_flash.light_time);
break;
//双灯互闪
case PWM_LED0_LED1_FAST_FLASH:
printf("led0_led1 fast flash:%d %d %d %d %d \n", led_para.one_flash.led0_bright, led_para.one_flash.led1_bright, \
led_para.one_flash.period, led_para.one_flash.start_light_time, \
led_para.one_flash.light_time);
_pwm_led_one_flash_display(2, \
led_para.one_flash.led0_bright, led_para.one_flash.led1_bright, \
led_para.one_flash.period, led_para.one_flash.start_light_time, \
led_para.one_flash.light_time);
break;
case PWM_LED0_LED1_SLOW_FLASH:
printf("led0_led1 slow flash:%d %d %d %d %d \n", led_para.one_flash.led0_bright, led_para.one_flash.led1_bright, \
led_para.one_flash.period, led_para.one_flash.start_light_time, \
led_para.one_flash.light_time);
_pwm_led_one_flash_display(2, \
led_para.one_flash.led0_bright, led_para.one_flash.led1_bright, \
led_para.one_flash.period, led_para.one_flash.start_light_time, \
led_para.one_flash.light_time);
break;
//单灯双闪
case PWM_LED0_DOUBLE_FLASH_5S:
printf("led0 double 5s:%d %d %d %d %d %d \n", led_para.double_flash.led0_bright, led_para.double_flash.led1_bright, \
led_para.double_flash.period, led_para.double_flash.first_light_time, \
led_para.double_flash.gap_time, led_para.double_flash.second_light_time);
_pwm_led_double_flash_display(2, \
led_para.double_flash.led0_bright, led_para.double_flash.led1_bright, \
led_para.double_flash.period, led_para.double_flash.first_light_time, \
led_para.double_flash.gap_time, led_para.double_flash.second_light_time);
break;
case PWM_LED1_DOUBLE_FLASH_5S:
printf("led1 double 5s:%d %d %d %d %d %d \n", led_para.double_flash.led0_bright, led_para.double_flash.led1_bright, \
led_para.double_flash.period, led_para.double_flash.first_light_time, \
led_para.double_flash.gap_time, led_para.double_flash.second_light_time);
_pwm_led_double_flash_display(2, \
led_para.double_flash.led0_bright, led_para.double_flash.led1_bright, \
led_para.double_flash.period, led_para.double_flash.first_light_time, \
led_para.double_flash.gap_time, led_para.double_flash.second_light_time);
break;
//呼吸模式
case PWM_LED0_BREATHE:
printf("led0 breathe:%d %d %d %d %d %d \n", led_para.breathe.breathe_time, led_para.breathe.led0_bright, \
led_para.breathe.led1_bright, led_para.breathe.led0_light_delay_time, \
led_para.breathe.led1_light_delay_time, led_para.breathe.led_blink_delay_time);
_pwm_led_breathe_display(0, \
led_para.breathe.breathe_time, led_para.breathe.led0_bright, \
led_para.breathe.led1_bright, led_para.breathe.led0_light_delay_time, \
led_para.breathe.led1_light_delay_time, led_para.breathe.led_blink_delay_time);
break;
case PWM_LED1_BREATHE:
printf("led1 breathe:%d %d %d %d %d %d \n", led_para.breathe.breathe_time, led_para.breathe.led0_bright, \
led_para.breathe.led1_bright, led_para.breathe.led0_light_delay_time, \
led_para.breathe.led1_light_delay_time, led_para.breathe.led_blink_delay_time);
_pwm_led_breathe_display(1, \
led_para.breathe.breathe_time, led_para.breathe.led0_bright, \
led_para.breathe.led1_bright, led_para.breathe.led0_light_delay_time, \
led_para.breathe.led1_light_delay_time, led_para.breathe.led_blink_delay_time);
break;
case PWM_LED0_LED1_BREATHE:
printf("led0_led1 breathe:%d %d %d %d %d %d \n", led_para.breathe.breathe_time, led_para.breathe.led0_bright, \
led_para.breathe.led1_bright, led_para.breathe.led0_light_delay_time, \
led_para.breathe.led1_light_delay_time, led_para.breathe.led_blink_delay_time);
_pwm_led_breathe_display(2, \
led_para.breathe.breathe_time, led_para.breathe.led0_bright, \
led_para.breathe.led1_bright, led_para.breathe.led0_light_delay_time, \
led_para.breathe.led1_light_delay_time, led_para.breathe.led_blink_delay_time);
break;
#else
case PWM_LED_ALL_OFF:
case PWM_LED0_OFF:
case PWM_LED1_OFF:
_pwm_led_off_display();
break;
//灯常亮
case PWM_LED0_ON:
_pwm_led_on_display(0, CFG_LED0_LIGHT, CFG_LED1_LIGHT);
break;
case PWM_LED1_ON:
_pwm_led_on_display(1, CFG_LED0_LIGHT, CFG_LED1_LIGHT);
break;
case PWM_LED_ALL_ON:
_pwm_led_on_display(2, CFG_LED0_LIGHT, CFG_LED1_LIGHT);
break;
//单灯单闪
case PWM_LED0_SLOW_FLASH:
_pwm_led_one_flash_display(0, CFG_LED0_LIGHT, CFG_LED1_LIGHT, CFG_SINGLE_SLOW_FLASH_FREQ, -1, CFG_SINGLE_SLOW_LIGHT_TIME);
break;
case PWM_LED1_SLOW_FLASH:
_pwm_led_one_flash_display(1, CFG_LED0_LIGHT, CFG_LED1_LIGHT, CFG_SINGLE_SLOW_FLASH_FREQ, -1, CFG_SINGLE_SLOW_LIGHT_TIME);
break;
case PWM_LED0_FAST_FLASH:
_pwm_led_one_flash_display(0, CFG_LED0_LIGHT, CFG_LED1_LIGHT, CFG_SINGLE_FAST_FLASH_FREQ, -1, CFG_SINGLE_FAST_LIGHT_TIME);
break;
case PWM_LED1_FAST_FLASH:
_pwm_led_one_flash_display(1, CFG_LED0_LIGHT, CFG_LED1_LIGHT, CFG_SINGLE_FAST_FLASH_FREQ, -1, CFG_SINGLE_FAST_LIGHT_TIME);
break;
case PWM_LED0_ONE_FLASH_5S:
_pwm_led_one_flash_display(0, CFG_LED0_LIGHT, CFG_LED1_LIGHT, 5000, 10, CFG_LED_5S_FLASH_LIGHT_TIME);
break;
case PWM_LED1_ONE_FLASH_5S:
_pwm_led_one_flash_display(1, CFG_LED0_LIGHT, CFG_LED1_LIGHT, 5000, 10, CFG_LED_5S_FLASH_LIGHT_TIME);
break;
//单灯双闪
case PWM_LED0_DOUBLE_FLASH_5S:
_pwm_led_double_flash_display(0, CFG_LED0_LIGHT, CFG_LED1_LIGHT, 5000, 100, 200, 100);
break;
case PWM_LED1_DOUBLE_FLASH_5S:
_pwm_led_double_flash_display(1, CFG_LED0_LIGHT, CFG_LED1_LIGHT, 5000, 100, 200, 100);
break;
//双灯互闪
case PWM_LED0_LED1_FAST_FLASH:
_pwm_led_one_flash_display(2, CFG_LED0_LIGHT, CFG_LED1_LIGHT, CFG_DOUBLE_FAST_FLASH_FREQ, -1, -1);
break;
case PWM_LED0_LED1_SLOW_FLASH:
_pwm_led_one_flash_display(2, CFG_LED0_LIGHT, CFG_LED1_LIGHT, CFG_DOUBLE_SLOW_FLASH_FREQ, -1, -1);
break;
//呼吸模式
case PWM_LED0_BREATHE:
_pwm_led_breathe_display(0, CFG_LED_BREATH_TIME, CFG_LED0_BREATH_BRIGHT, CFG_LED1_BREATH_BRIGHT, 0, 0, CFG_LED_BREATH_BLINK_TIME);
break;
case PWM_LED1_BREATHE:
_pwm_led_breathe_display(1, CFG_LED_BREATH_TIME, CFG_LED0_BREATH_BRIGHT, CFG_LED1_BREATH_BRIGHT, 0, 0, CFG_LED_BREATH_BLINK_TIME);
break;
case PWM_LED0_LED1_BREATHE:
_pwm_led_breathe_display(2, CFG_LED_BREATH_TIME, CFG_LED0_BREATH_BRIGHT, CFG_LED1_BREATH_BRIGHT, 0, 0, CFG_LED_BREATH_BLINK_TIME);
break;
#endif
}
}
static void _pwm_led_user_define_mode_handle(u8 dis_mode)
{
return;
}
//=================================================================================//
// 以下为 LED API //
//=================================================================================//
//=================================================================================//
//@brief: LED模式显示模式设置
//@input: display, 显示模式
//@return: void
//@note:
//=================================================================================//
void pwm_led_mode_set(u8 display)
{
if (__this->init == 0) {
led_debug("led no init");
return;
}
#if TCFG_ADKEY_LED_IO_REUSE
if (!((display >= PWM_LED0_ON) && (display <= PWM_LED0_ONE_FLASH_5S) || display == PWM_LED0_BREATHE || display == PWM_LED0_FLASH_THREE)) {
led_debug("ADKEY_LED_IO_REUSR only can set blueled\n");
return;
}
#endif
led_debug("Mode %d Display", display);
if (display == PWM_LED_NULL) {
return;
}
if (((display >= PWM_LED_USER_DEFINE_BEGIN) && (display <= PWM_LED_USER_DEFINE_END))) {
//用户自定义模式
if (display != __this->last_mode) {
_pwm_led_user_define_mode_handle(display);
}
return;
}
if ((display >= PWM_LED_MODE_END)/* || (display == __this->last_mode)*/) {
return;
}
if ((display == PWM_LED_ALL_OFF) || (display == PWM_LED0_OFF) || (display == PWM_LED1_OFF)) {
led_pwm_pre_set(); //关LED
__this->last_mode = display;
return;
}
_pwm_led_close_irq();
if (__this->user_data->io_mode == LED_TWO_IO_MODE) {
pwm_led_two_io_mode_display(display);
} else {
pwm_led_one_io_mode_display(display);
}
__this->last_mode = display;
log_pwm_led_info();
}
//=================================================================================//
//@brief: LED模块时钟源选择
//@input: src, 时钟源BT24M/RC32K
//@return: void
//@note:
//=================================================================================//
void pwm_led_clk_set(enum pwm_led_clk_source src)
{
return;
}
//=================================================================================//
//@brief: LED显示周期复位, 重新开始一个周期, 可用于同步等操作
//@input: void
//@return: void
//@note:
//=================================================================================//
void pwm_led_display_mode_reset(void)
{
LED_PWM_DISABLE;
LED_PWM_ENABLE;
}
//=================================================================================//
//@brief: 获取LED当前显示模式
//@input: void
//@return: 当前LED显示模式
//@note:
//=================================================================================//
enum pwm_led_mode pwm_led_display_mode_get(void)
{
return __this->last_mode;
}
//=================================================================================//
//@brief: 修改LED灯IO口驱动能力,
//@input: void
//@return: 当前LED显示模式
//@note:
//挡位: 0 ~ 3
// 0: 2.4mA(8mA mos + 120Ωres)
// 1: 8mA(8mA mos)
// 2: 18.4mA(24mA mos + 120Ωres)
// 3: 24mA(24mA mos)
//=================================================================================//
void pwm_led_io_max_drive_set(u8 strength)
{
LED_PWM_IO_MAX_DRIVE(strength);
}
//=================================================================================//
//@brief: 获取LED模块是否开启, 可用于sniff灯同步
//@input: void
//@return: 0: 模块开启; 1: 模块关闭
//@note:
//=================================================================================//
u8 is_pwm_led_on(void)
{
return IS_PWM_LED_ON;
}
//=================================================================================//
//@brief: 获取LED模块开启, 可用于sniff灯同步
//@input: void
//@return: void
//@note:
//=================================================================================//
void pwm_led_set_on(void)
{
LED_PWM_ENABLE;
}
//=================================================================================//
//@brief: 获取LED模块关闭, 可用于sniff灯同步
//@input: void
//@return: void
//@note:
//=================================================================================//
void pwm_led_set_off(void)
{
LED_PWM_DISABLE;
}
//=================================================================================//
//@brief: 自定义设置单灯闪状态
//@input: void
// led_index: 0: led0, 1:led1, 2:led0 & led1(互闪)
// led0_bright: led0亮度(0 ~ 500),
// led1_bright: led1亮度(0 ~ 500),
// period: 闪灯周期(ms), 多少ms闪一下,
// start_light_time: 在周期中开始亮灯的时间, -1: 周期最后亮灯, 默认填-1即可,
// light_time: 灯亮持续时间(ms),
//@return: void
//@note:
//=================================================================================//
void pwm_led_one_flash_display(u8 led_index, u16 led0_bright, u16 led1_bright,
u32 period, u32 start_light_time, u32 light_time)
{
_pwm_led_close_irq();
//两个IO特殊处理
if (__this->user_data->io_mode == LED_TWO_IO_MODE) {
#ifdef PWM_LED_TWO_IO_SUPPORT
_pwm_led_two_io_user_define_mode(led_index);
if (led_index == 0) {
led_index = 1;
led1_bright = led0_bright;
}
#endif /* #ifdef PWM_LED_TWO_IO_SUPPORT */
}
_pwm_led_one_flash_display(led_index, led0_bright, led1_bright,
period, start_light_time, light_time);
__this->last_mode = PWM_LED_USER_DEFINE_MODE;
}
//=================================================================================//
//@brief: 自定义设置单灯双闪状态
//@input:
// led_index: 0: led0, 1:led1, 3:led0 & led1(互闪)
// led0_bright: led0亮度,
// led1_bright: led1亮度,
// period: 闪灯周期(ms), 多少ms闪一下
// first_light_time: 第一次亮灯持续时间,
// second_light_time: 第二次亮灯持续时间,
// gap_time: 两次亮灯时间间隔,
// led0_bright, LED0亮度: 0 ~ 500
// led1_bright, LED1亮度: 0 ~ 500
//@return: void
//@note:
//=================================================================================//
void pwm_led_double_flash_display(u8 led_index, u16 led0_bright, u16 led1_bright,
u32 period, u32 first_light_time, u32 gap_time, u32 second_light_time)
{
_pwm_led_close_irq();
//两个IO特殊处理
if (__this->user_data->io_mode == LED_TWO_IO_MODE) {
#ifdef PWM_LED_TWO_IO_SUPPORT
_pwm_led_two_io_user_define_mode(led_index);
if (led_index == 0) {
led_index = 1;
led1_bright = led0_bright;
}
led_index = 0;
#endif /* #ifdef PWM_LED_TWO_IO_SUPPORT */
}
_pwm_led_double_flash_display(led_index, led0_bright, led1_bright,
period, first_light_time, gap_time, second_light_time);
__this->last_mode = PWM_LED_USER_DEFINE_MODE;
}
//=================================================================================//
//@brief: 自定义设置呼吸模式
//@input:
// led_index: 0: led0, 1:led1, 2:led0 & led1(互闪)
// led0_bright: led0亮度,
// led1_bright: led1亮度,
// period: 闪灯周期(ms), 多少ms闪一下,
// start_light_time: 在周期中开始亮灯的时间, -1: 周期最后亮灯
// light_time: 灯亮持续时间,
// led0_bright, LED0亮度: 0 ~ 500
// led1_bright, LED1亮度: 0 ~ 500
//@return: void
//@note:
//=================================================================================//
void pwm_led_breathe_display(u8 led_index, u16 breathe_time, u16 led0_bright, u16 led1_bright,
u32 led0_light_delay_time, u32 led1_light_delay_time, u32 led_blink_delay_time)
{
_pwm_led_close_irq();
if (__this->user_data->io_mode == LED_TWO_IO_MODE) {
#ifdef PWM_LED_TWO_IO_SUPPORT
_pwm_led_two_io_user_define_mode(led_index);
if (led_index == 0) {
led_index = 1;
led1_bright = led0_bright;
}
#endif /* #ifdef PWM_LED_TWO_IO_SUPPORT */
}
_pwm_led_breathe_display(led_index, breathe_time, led0_bright, led1_bright,
led0_light_delay_time, led1_light_delay_time, led_blink_delay_time);
__this->last_mode = PWM_LED_USER_DEFINE_MODE;
}
//=================================================================================//
//@brief: 注册LED周期中断函数, 每个LED周期结束后会调用一次, 可以统计指定状态闪烁多少次
//@input:
//@return: void
//@note:
//=================================================================================//
void pwm_led_register_irq(void (*func)(void))
{
_pwm_led_register_irq(func, 1);
}
//=================================================================================//
//@brief: LED模式显示参数设置
//@input: display, 显示模式
// para 显示的参数
//@return: void
//@note:
//=================================================================================//
static void pwm_led_para_set(u8 display, pwm_led_para para)
{
switch (display) {
case PWM_LED_ALL_OFF:
case PWM_LED0_OFF:
case PWM_LED1_OFF:
break;
//灯常亮
case PWM_LED0_ON:
case PWM_LED1_ON:
case PWM_LED_ALL_ON:
led_para.on = para.on;
break;
//单灯单闪
case PWM_LED0_SLOW_FLASH:
case PWM_LED1_SLOW_FLASH:
case PWM_LED0_FAST_FLASH:
case PWM_LED1_FAST_FLASH:
case PWM_LED0_ONE_FLASH_5S:
case PWM_LED1_ONE_FLASH_5S:
//双灯互闪
case PWM_LED0_LED1_FAST_FLASH:
case PWM_LED0_LED1_SLOW_FLASH:
led_para.one_flash = para.one_flash;
break;
//单灯双闪
case PWM_LED0_DOUBLE_FLASH_5S:
case PWM_LED1_DOUBLE_FLASH_5S:
led_para.double_flash = para.double_flash;
break;
//呼吸模式
case PWM_LED0_BREATHE:
case PWM_LED1_BREATHE:
case PWM_LED0_LED1_BREATHE:
led_para.breathe = para.breathe;
break;
default:
return;
break;
}
}
//=================================================================================//
//@brief: LED模式显示模式设置
//@input: display, 显示模式
//@return: void
//@note:
//=================================================================================//
void pwm_led_mode_set_with_para(u8 display, pwm_led_para para)
{
pwm_led_para_set(display, para);
pwm_led_mode_set(display);
}
//=================================================================================//
//@brief:
//@input:
//@return:
//@note:
//=================================================================================//
void _pwm_cycle_duty_set(struct pwm_cycle_pattern *pattern)
{
u8 duty0 = 0;
u8 duty1 = 0;
u8 duty2 = 0;
u8 duty3 = 0;
duty0 = (256 * pattern->holdtime1_ms) / pattern->cycle_ms;
if (duty0 == 0) {
duty0 = 1;
}
duty1 = (256 * pattern->holdtime2_ms) / pattern->cycle_ms;
if (duty1 == 0) {
duty1 = 2;
}
duty2 = (256 * pattern->holdtime3_ms) / pattern->cycle_ms;
if (duty2 == 0) {
duty2 = 2;
}
duty3 = (256 * pattern->holdtime4_ms) / pattern->cycle_ms;
if (duty3 == 0) {
duty3 = 2;
}
duty1 += duty0;
duty2 += duty1;
duty3 += duty2;
LED_PWM1_DUTY0_SET(duty0);
LED_PWM1_DUTY0_EN;
if (pattern->holdtime2_ms) {
LED_PWM1_DUTY1_SET(duty1);
LED_PWM1_DUTY1_EN;
} else {
LED_PWM1_DUTY1_DIS;
}
if (pattern->holdtime3_ms) {
LED_PWM1_DUTY2_SET(duty2);
LED_PWM1_DUTY2_EN;
} else {
LED_PWM1_DUTY2_DIS;
}
if (pattern->holdtime4_ms) {
LED_PWM1_DUTY3_SET(duty3);
LED_PWM1_DUTY3_EN;
} else {
LED_PWM1_DUTY3_DIS;
}
}
//=================================================================================//
//@brief:
//@input:
//@return:
//@note:
//=================================================================================//
void pwm_cycle_pattern_init(struct pwm_cycle_pattern *pattern)
{
u16 pwm0_prd = 500;
u16 pwm0_div = 0;
LED_PWM_DISABLE;
LED_PWM_BREATHE_DISABLE;
if (__this->clock == PWM_LED_CLK_RC32K) {
_led_pwm0_clk_set(PWM0_CLK_32K);
pwm0_div = (PWM0_RC_CLK32K_VALUE * pattern->cycle_ms) / (1000 * 256);
} else {
if (pattern->cycle_ms < 22000) {
_led_pwm0_clk_set(PWM0_CLK_46K);
pwm0_div = (PWM0_BT_CLK46K_VALUE * pattern->cycle_ms) / (1000 * 256);
} else {
_led_pwm0_clk_set(PWM0_CLK_23K);
pwm0_div = (PWM0_BT_CLK23K_VALUE * pattern->cycle_ms) / (1000 * 256);
pwm0_prd = 300;
pattern->led_L_bright = (pattern->led_L_bright * 300) / 500;
pattern->led_H_bright = (pattern->led_H_bright * 300) / 500;
}
}
_led_pwm1_clk_set(pwm0_div);
u8 out_inv = 0;
switch (pattern->led_type) {
case 0:
out_inv = 1;
break;
case 1:
break;
}
_led_pwm_bright_set(pwm0_prd, pattern->led_L_bright, pattern->led_H_bright);
_led_pwm_output_logic_set(out_inv, pattern->shift_duty);
LED_PWM1_INV_DISABLE;//起始电平为灭灯
_pwm_cycle_duty_set(pattern);
_led_pwm_module_enable(1, 0);
}
//=================================================================================//
//@brief:
//@input:
//@return:
//@note:
//=================================================================================//
void pwm_breathe_pattern_init(struct pwm_breathe_pattern *pattern)
{
u16 led0_bri_duty = pattern->led_L_bright;
u16 led1_bri_duty = pattern->led_H_bright;
u16 pwm1_div = 0;
u16 Tpwm1 = 0;
pwm1_div = led0_bri_duty > led1_bri_duty ? led0_bri_duty : led1_bri_duty;
LED_PWM_DISABLE;
LED_PWM_BREATHE_DISABLE;
u16 breathe_time = pattern->breathe_time / 2; //呼吸总时间, 单个灭到最亮的时间
if (__this->clock == PWM_LED_CLK_RC32K) {
_led_pwm0_clk_set(PWM0_CLK_32K);
pwm1_div = breathe_time * 32 / pwm1_div;
Tpwm1 = (pwm1_div * 1000 / 32000); //ms
} else {
_led_pwm0_clk_set(PWM0_CLK_46K);
pwm1_div = breathe_time * 46 / pwm1_div;
Tpwm1 = (pwm1_div * 1000 / 46000); //ms
}
_led_pwm1_clk_set(pwm1_div);
u8 out_inv = 0;
switch (pattern->led_type) {
case 0://低亮灯
out_inv = 1;
break;
case 1://高亮灯
break;
}
_led_pwm_bright_set(500, led0_bri_duty, led1_bri_duty);
_led_pwm_output_logic_set(out_inv, pattern->shift_duty * 2);
u8 pwm1_duty0 = 0;
u8 pwm1_duty1 = 0;
u8 pwm1_duty2 = 0;
u8 pwm1_duty3 = 0xFF;
if (Tpwm1 == 0) {
pattern->led_L_holdtime *= 2;
pattern->led_H_holdtime *= 2;
pattern->breathe_interval *= 2;
Tpwm1 = 1;
}
pwm1_duty0 = pattern->led_L_holdtime / Tpwm1;
pwm1_duty1 = pattern->led_H_holdtime / Tpwm1;
pwm1_duty2 = (pattern->breathe_interval / Tpwm1) & 0xFF;
pwm1_duty3 = ((pattern->breathe_interval / Tpwm1) >> 8) & 0xFF;
_led_pwm1_duty_set(pwm1_duty3, pwm1_duty0, pwm1_duty1, pwm1_duty2, 1);
_led_pwm_module_enable(1, 1);
}
void led_pwm_clear_pending()
{
LED_PWM_CLR_PENDING;
}
void led_pwm_isr_en(u8 en)
{
if (en) {
LED_PWM_INT_EN;
} else {
LED_PWM_INT_DIS;
}
}
void pwmled_pwm_init()
{
memset(__this, 0, sizeof(struct pwm_led));
LED_PWM_DISABLE;
LED_PWM_BREATHE_DISABLE; //呼吸灯使能位
RESET_PWM_CON0;
RESET_PWM_CON1;
RESET_PWM_CON2;
RESET_PWM_CON3;
LED_PWM_OUT_LOGIC_SET;
LED_PWM_CLR_PENDING;
pwm_clock_set(PWM_LED_CLK_BTOSC_24M);
}
static u8 led_io_sus = 0;
u8 led_io_suspend(void)
{
if (led_io_sus) {
return 1;
}
led_io_sus = 1;
return 0;
}
u8 led_io_resume(void)
{
if (!led_io_sus) {
return 0;
}
led_io_sus = 0;
gpio_set_pull_up(__this->led_pin, 1);
gpio_set_pull_down(__this->led_pin, 1);
gpio_set_die(__this->led_pin, 1);
gpio_set_output_value(__this->led_pin, 1);
gpio_set_direction(__this->led_pin, 0);
return 0;
}