390 lines
10 KiB
C
390 lines
10 KiB
C
#include "include.h"
|
||
#include "func.h"
|
||
|
||
void bsp_qdec_init(void);
|
||
|
||
AT(.com_rodata.key.table)
|
||
const key_shake_tbl_t key_shake_table = {
|
||
.scan_cnt = KEY_SCAN_TIMES,
|
||
.up_cnt = KEY_UP_TIMES,
|
||
.long_cnt = KEY_LONG_TIMES,
|
||
.hold_cnt = KEY_LONG_HOLD_TIMES,
|
||
};
|
||
|
||
#if USER_ADKEY
|
||
AT(.com_text.port.key)
|
||
static u8 get_adkey(u8 key_val)
|
||
{
|
||
u8 num = 0;
|
||
|
||
while (key_val > adkey_table[num].adc_val) {
|
||
num++;
|
||
}
|
||
|
||
return adkey_table[num].usage_id;
|
||
}
|
||
#endif // USER_ADKEY
|
||
|
||
#if USER_PWRKEY
|
||
AT(.com_text.port.key)
|
||
static u8 get_pwrkey(void)
|
||
{
|
||
u8 num = 0;
|
||
u32 wko_val = saradc_get_value10(ADCCH_WKO);
|
||
u16 key_val = ((u32)wko_val << 8) / adc_cb.vrtc_val;
|
||
|
||
if (key_val > 0xff) {
|
||
key_val = 0xff;
|
||
}
|
||
while ((u8)key_val > pwrkey_table[num].adc_val) {
|
||
num++;
|
||
}
|
||
return pwrkey_table[num].usage_id;
|
||
}
|
||
#endif // USER_PWRKEY
|
||
|
||
bool power_off_check(void)
|
||
{
|
||
#if CHARGE_EN
|
||
u16 charge_cnt = 0;
|
||
#endif
|
||
u32 pwron_press_nms;
|
||
int pwrkey_pressed_flag, ticks = 0, up_cnt = 0;
|
||
u8 restart_chk_en = 1;
|
||
|
||
pwrkey_pressed_flag = 0;
|
||
pwron_press_nms = PWRON_PRESS_TIME;
|
||
if (pwron_press_nms == 0) {
|
||
pwron_press_nms = 100;
|
||
}
|
||
|
||
//要等PWRKEY开关释放后再次按下才能重新开机, 否则充电过程中5分钟关机, 低电关机等异常
|
||
if ((PWRKEY_2_HW_PWRON) && (sys_cb.poweron_flag)) {
|
||
restart_chk_en = 0;
|
||
sys_cb.poweron_flag = 0;
|
||
}
|
||
|
||
while (1) {
|
||
WDT_CLR();
|
||
delay_ms(5);
|
||
if (get_pwrkey() == key_cb.pwr_usage_id) {
|
||
up_cnt = 0;
|
||
if (restart_chk_en) {
|
||
if (!pwrkey_pressed_flag) {
|
||
ticks = tick_get();
|
||
pwrkey_pressed_flag = 1;
|
||
sys_cb.ms_ticks = tick_get(); //记录PWRKEY按键按下的时刻
|
||
}
|
||
if (!sys_cb.poweron_flag) {
|
||
if (tick_check_expire(ticks, pwron_press_nms)) { //长按开机时间配置
|
||
sys_cb.poweron_flag = 1;
|
||
sys_cb.pwrdwn_hw_flag = 0; //清PWRKEY硬开关的关机标志
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
if (up_cnt < 3) {
|
||
up_cnt++;
|
||
}
|
||
if (up_cnt == 3) {
|
||
up_cnt = 10;
|
||
sys_cb.poweron_flag = 0;
|
||
pwrkey_pressed_flag = 0;
|
||
restart_chk_en = 1;
|
||
}
|
||
}
|
||
|
||
#if CHARGE_EN
|
||
if (xcfg_cb.charge_en) {
|
||
charge_cnt++;
|
||
if (charge_cnt > 20) {
|
||
charge_cnt = 0;
|
||
charge_detect(0);
|
||
}
|
||
}
|
||
#endif // CHARGE_EN
|
||
|
||
if (sys_cb.poweron_flag) {
|
||
if ((CHARGE_DC_NOT_PWRON) && CHARGE_DC_IN()) {
|
||
continue;
|
||
}
|
||
//长按PP/POWER开机
|
||
dac_restart();
|
||
bsp_change_volume(sys_cb.vol);
|
||
#if WARNING_POWER_ON
|
||
mp3_res_play(RES_BUF_POWERON_MP3, RES_LEN_POWERON_MP3);
|
||
#endif // WARNING_POWER_ON
|
||
func_cb.sta = FUNC_CLOCK;
|
||
return true;
|
||
} else {
|
||
if (CHARGE_DC_IN()) {
|
||
continue;
|
||
} else {
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
AT(.text.bsp.power)
|
||
bool is_powron_frist_enable(u32 rtccon9)
|
||
{
|
||
if (!PWRON_FRIST_BAT_EN) {
|
||
return false;
|
||
}
|
||
if (rtccon9 & BIT(2)) { //WKO wakeup不能直接开机
|
||
return false;
|
||
}
|
||
if (CHARGE_DC_IN() && (CHARGE_DC_NOT_PWRON)) { //VUSB充电禁止开机
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
AT(.text.bsp.power)
|
||
void power_on_check(void)
|
||
{
|
||
#if CHARGE_EN
|
||
u16 charge_cnt = 0;
|
||
#endif
|
||
int pwrkey_pressed_flag = 0;
|
||
u32 pwron_press_nms;
|
||
u32 rtccon9 = RTCCON9; //wakeup pending
|
||
|
||
RTCCON9 = 0xfff; //Clr pending
|
||
RTCCON10 = 0xfff; //Clr pending
|
||
RTCCON1 &= ~BIT(6); //wko pin low level wakeup
|
||
|
||
if (LVDCON & BIT(19)) {
|
||
if (IS_PWRKEY_PRESS()) {
|
||
sys_cb.poweron_flag = 1;
|
||
}
|
||
return; //长按PWRKEY 10S复位后直接开机。
|
||
}
|
||
|
||
if (rtccon9 & BIT(0)) {
|
||
printf("alarm wakeup\n");
|
||
return;
|
||
}
|
||
|
||
#if USER_PWRKEY
|
||
int up_cnt = 0, ticks = 0;
|
||
if (!IS_PWRKEY_PRESS()) {
|
||
pwrkey_pressed_flag = 1;
|
||
ticks = sys_cb.ms_ticks;
|
||
}
|
||
#endif // USER_PWRKEY
|
||
|
||
pwron_press_nms = PWRON_PRESS_TIME;
|
||
if (pwron_press_nms < 100) {
|
||
pwron_press_nms = 100; //最小开机时间在100ms左右
|
||
}
|
||
|
||
//第一次上电是否直接开机
|
||
if (is_powron_frist_enable(rtccon9)) {
|
||
return;
|
||
}
|
||
|
||
while (1) {
|
||
WDT_CLR();
|
||
delay_ms(5);
|
||
|
||
u8 key_val = bsp_key_scan();
|
||
if ((key_val & KEY_USAGE_MASK) == key_cb.pwr_usage_id) {
|
||
up_cnt = 0;
|
||
if (!pwrkey_pressed_flag) {
|
||
ticks = tick_get();
|
||
sys_cb.ms_ticks = ticks; //记录PWRKEY按键按下的时刻
|
||
pwrkey_pressed_flag = 1;
|
||
}
|
||
if (!sys_cb.poweron_flag) {
|
||
if (tick_check_expire(ticks, pwron_press_nms)) { //长按开机时间配置
|
||
sys_cb.poweron_flag = 1;
|
||
}
|
||
}
|
||
} else {
|
||
if (up_cnt < 3) {
|
||
up_cnt++;
|
||
}
|
||
if (up_cnt == 3) {
|
||
up_cnt = 10;
|
||
pwrkey_pressed_flag = 0;
|
||
sys_cb.poweron_flag = 0;
|
||
}
|
||
}
|
||
|
||
#if CHARGE_EN
|
||
if (xcfg_cb.charge_en) {
|
||
charge_cnt++;
|
||
if ((charge_cnt % 20) == 0) {
|
||
charge_detect(0);
|
||
}
|
||
if (charge_cnt >= 200) { //1S
|
||
charge_cnt = 0;
|
||
}
|
||
//充满且蓝灯已灭,进入关机状态
|
||
if ((sys_cb.charge_sta == 2) && (!sys_cb.charge_bled_flag)) {
|
||
bsp_saradc_exit();
|
||
sfunc_pwrdown(0);
|
||
}
|
||
}
|
||
#endif // CHARGE_EN
|
||
|
||
if (sys_cb.poweron_flag) {
|
||
__pwron:
|
||
#if VBAT_DETECT_EN
|
||
if (sys_cb.vbat <= LPWR_OFF_VBAT) { //电压小于3.1v不开机
|
||
continue;
|
||
}
|
||
#endif
|
||
if ((CHARGE_DC_NOT_PWRON) && CHARGE_DC_IN()) {
|
||
continue;
|
||
}
|
||
//长按PP/POWER开机
|
||
break;
|
||
} else {
|
||
//PWKKEY松开,立刻关机
|
||
if (!pwrkey_pressed_flag) {
|
||
if (!CHARGE_DC_IN()) {
|
||
if ((!SOFT_POWER_ON_OFF) || ((!USER_PWRKEY) && (!PWRKEY_2_HW_PWRON))) {
|
||
goto __pwron; //没有软开关机功能,直接开机。
|
||
}
|
||
bsp_saradc_exit();
|
||
// sfunc_pwrdown(1);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void key_init(void)
|
||
{
|
||
key_var_init();
|
||
|
||
#if USER_IOKEY
|
||
io_key_init();
|
||
#endif
|
||
|
||
#if USER_ADKEY
|
||
saradc_set_channel(BIT(ADKEY_CH));
|
||
// adcch_io_pu10k_enable(ADKEY_CH); //开内部10K上拉
|
||
#endif
|
||
|
||
#if USER_PWRKEY
|
||
saradc_set_channel(BIT(ADCCH_VRTC) | BIT(ADCCH_WKO));
|
||
key_cb.pwr_usage_id = pwrkey_table[USER_PWRON_KEY_SEL].usage_id; //开关机按键定义
|
||
#endif
|
||
|
||
#if VBAT_DETECT_EN
|
||
saradc_set_channel(BIT(ADCCH_BGOP) | BIT(VBAT2_ADCCH));
|
||
#endif
|
||
|
||
#if USER_KEY_QDEC_EN || USER_ADKEY_QDEC_EN
|
||
bsp_qdec_init(); //旋转编码器初始化
|
||
#endif
|
||
|
||
bsp_saradc_init();
|
||
power_on_check();
|
||
CRSTPND = 0x1ff0000; //clear reset pending
|
||
}
|
||
|
||
AT(.com_text.bsp.key)
|
||
bool get_poweron_flag(void)
|
||
{
|
||
return sys_cb.poweron_flag;
|
||
}
|
||
|
||
AT(.com_text.bsp.key)
|
||
void set_poweron_flag(bool flag)
|
||
{
|
||
sys_cb.poweron_flag = flag;
|
||
}
|
||
|
||
u8 get_pwroff_pressed_time(void)
|
||
{
|
||
return PWROFF_PRESS_TIME;
|
||
}
|
||
|
||
u8 get_double_key_time(void)
|
||
{
|
||
if (USER_MULTI_KEY_TIME > 8) {
|
||
return 70;
|
||
} else {
|
||
return (u8)(USER_MULTI_KEY_TIME*20 + 1);
|
||
}
|
||
}
|
||
|
||
//AT(.com_rodata.bsp.key)
|
||
//const char key_str[] = "enqueue: %04x\n";
|
||
|
||
AT(.com_text.bsp.key)
|
||
u16 bsp_key_process(u16 key_val)
|
||
{
|
||
u16 key_return = NO_KEY, key;
|
||
key_return = key_process(key_val);
|
||
key = key_return;
|
||
|
||
//多击处理
|
||
#if USER_MULTI_PRESS_EN
|
||
key_return = key_multi_press_process(key_return);
|
||
if (key != key_return && (key & KEY_TYPE_MASK) == KEY_SHORT_UP) {
|
||
msg_enqueue(key); //short up key
|
||
// printf(key_str, key);
|
||
}
|
||
#endif
|
||
return key_return;
|
||
}
|
||
|
||
AT(.com_text.bsp.key)
|
||
u8 bsp_key_scan(void)
|
||
{
|
||
u8 key_val = NO_KEY;
|
||
u16 key = NO_KEY;
|
||
|
||
#if VBAT_DETECT_EN
|
||
if (adc_vbat2_flag) {
|
||
adc_vbat2_flag = false;
|
||
sys_cb.vbat = bsp_vbat_get_voltage();
|
||
}
|
||
#endif
|
||
|
||
#if USER_ADKEY
|
||
if (key_val == NO_KEY) {
|
||
key_val = get_adkey(saradc_get_value8(ADKEY_CH));
|
||
}
|
||
#endif // USER_ADKEY
|
||
|
||
#if USER_PWRKEY
|
||
if (key_val == NO_KEY) {
|
||
key_val = get_pwrkey();
|
||
}
|
||
#endif // USER_PWRKEY
|
||
|
||
#if USER_IOKEY
|
||
if (key_val == NO_KEY) {
|
||
key_val = get_iokey();
|
||
}
|
||
#endif // USER_IOKEY
|
||
|
||
key = bsp_key_process(key_val);
|
||
if (key != NO_KEY) {
|
||
//防止enqueue多次HOLD消息
|
||
if ((key & KEY_TYPE_MASK) == KEY_LONG) {
|
||
sys_cb.kh_vol_msg = (key & KEY_USAGE_MASK) | KEY_HOLD;
|
||
} else if ((key & KEY_TYPE_MASK) == KEY_LONG_UP) {
|
||
msg_queue_detach(sys_cb.kh_vol_msg, 0);
|
||
sys_cb.kh_vol_msg = NO_KEY;
|
||
} else if (sys_cb.kh_vol_msg == key) {
|
||
msg_queue_detach(key, 0);
|
||
}
|
||
// printf(key_str, key);
|
||
if (sys_cb.gui_sleep_sta) {
|
||
sys_cb.gui_need_wakeup = 1;
|
||
}
|
||
msg_enqueue(key);
|
||
reset_sleep_delay_all();
|
||
}
|
||
return key_val;
|
||
}
|
||
|