| /****************************************************************************** |
| * @file app_ui.c |
| * |
| * @brief for TLSR chips |
| * |
| * @author public@telink-semi.com; |
| * @date Sep. 30, 2010 |
| * |
| * @attention |
| * |
| * Copyright (C) 2019-2020 Telink Semiconductor (Shanghai) Co., Ltd. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| *****************************************************************************/ |
| |
| #include "tl_common.h" |
| #include "drivers.h" |
| #include "stack/ble/ble.h" |
| #include "app_config.h" |
| |
| #include "application/keyboard/keyboard.h" |
| #include "application/usbstd/usbkeycode.h" |
| #include "../common/blt_led.h" |
| #include "../common/blt_soft_timer.h" |
| |
| #include "rc_ir.h" |
| #include "battery_check.h" |
| #include "app_audio.h" |
| #include "app_flash_write.h" |
| #include "app_ir.h" |
| |
| #if (MP_TEST_MODE) |
| #include "app_test.h" |
| #endif |
| |
| #include "app_custom.h" |
| |
| //////////////////// key type /////////////////////// |
| #define IDLE_KEY 0 |
| #define CONSUMER_KEY 1 |
| #define KEYBOARD_KEY 2 |
| #define IR_KEY 3 |
| #define VOICE_KEY 4 |
| |
| _attribute_data_retention_ u8 key_type; |
| _attribute_data_retention_ int key_not_released; |
| |
| |
| _attribute_data_retention_ u8 ota_is_working = 0; |
| |
| |
| |
| |
| _attribute_data_retention_ int ir_not_released=0; |
| _attribute_data_retention_ u8 user_key_mode; |
| u8 ir_hw_initialed = 0; //note: can not be retention variable |
| _attribute_data_retention_ u8 repairing_flag = 0; |
| _attribute_data_retention_ u8 is_pairing_mode=0; |
| _attribute_data_retention_ u8 is_reconn_mode=0; |
| _attribute_data_retention_ u8 ota_flag = 0; //0:pause 1:continue |
| |
| extern u8 comb_key_keyid[8]; |
| extern u32 latest_user_event_tick; |
| extern u8 lowbat; |
| extern int device_in_connection_state; |
| extern u8 flag_schedule_ota; |
| extern u8 device_timeout_state; |
| extern u8 wakeup_src; |
| extern u8 power_down_flag; |
| extern u8 wakeup_key_keyid; |
| extern u8 wakeup_key_send_flag; |
| extern u8 wakeup_packet_format; |
| extern u32 wakeup_tick; |
| extern u32 advertise_begin_tick; |
| extern u8 en_powerkey_cache; |
| |
| extern int ir_fallback_send(u8 key_down); |
| extern void device_led_off(u8 led); |
| extern void app_enter_deep_timeset(void); |
| extern void app_set_adv_interval_downgrade_indirect(void); |
| extern void app_tx_power_wakeup(u8 keyid); |
| extern u8 app_custom_is_wakeup_key(u8 keyid); |
| extern ble_sts_t app_terminate(u8 reason); |
| static const u16 vk_consumer_map[] = { |
| G00GLE_MKEY_INFO, |
| G00GLE_MKEY_SUBTITLE, |
| G00GLE_MKEY_RED, |
| G00GLE_MKEY_GREEN, |
| G00GLE_MKEY_YELLOW, |
| G00GLE_MKEY_BLUE, |
| G00GLE_MKEY_YOUTUBE, |
| G00GLE_MKEY_NETFLIX, |
| G00GLE_MKEY_DISNEY, |
| G00GLE_MKEY_HBOMAX, |
| G00GLE_MKEY_UP, |
| G00GLE_MKEY_DN, |
| G00GLE_MKEY_LEFT, |
| G00GLE_MKEY_RIGHT, |
| G00GLE_MKEY_CENTER, |
| G00GLE_MKEY_HOME, |
| G00GLE_MKEY_BACK, |
| G00GLE_MKEY_POWER, |
| G00GLE_MKEY_VOL_MUTE, |
| G00GLE_MKEY_CHN_UP, |
| G00GLE_MKEY_CHN_DN, |
| G00GLE_MKEY_GUIDE, |
| G00GLE_MKEY_BOOKMARK, |
| G00GLE_MKEY_ASSIST, |
| G00GLE_MKEY_INPUT, |
| G00GLE_MKEY_DASHBOARD, |
| }; |
| |
| |
| /////////////////////////// led management ///////////////////// |
| #if (BLT_APP_LED_ENABLE) |
| |
| enum{ |
| LED_POWER_ON = 0, |
| LED_AUDIO_ON, //1 |
| LED_AUDIO_OFF, //2 |
| LED_SHINE_SLOW, //3 |
| LED_SHINE_FAST, //4 |
| LED_SHINE_SUCCESS, //5 |
| LED_SHINE_PAIRING, //6 |
| LED_SHINE_PTT, //7 |
| LED_SHINE_LOWBAT, |
| LED_PAIR_ERROR, |
| LED_OTA_START, |
| LED_OTA_END, |
| LED_KEYPRESS |
| }; |
| |
| const led_cfg_t led_cfg[] = { |
| {APP_LED_GREEN, 1, 1000, 0, 1, 0, }, //power-on, 1s on |
| {APP_LED_GREEN, 1, 100, 0 , 0, 1, }, //audio on, long on |
| {APP_LED_GREEN, 0, 0, 100 , 0, 1, }, //audio off, long off |
| {APP_LED_GREEN, 1, 500, 500 , 2, 0, }, //1Hz for 3 seconds |
| {APP_LED_GREEN, 1, 100, 100 , 1, 0, }, //5Hz for 3 seconds |
| {APP_LED_GREEN, 0, 100, 100 , 2, 0, }, //2Hz for 50 seconds |
| {APP_LED_GREEN, 1, 250, 250 , 0, 0, }, //2Hz |
| {APP_LED_GREEN, 1, 500, 500 , 0, 0, }, //1Hz |
| {APP_LED_RED, 1, 100, 100 , 5, 0, }, //5Hz for 5 seconds |
| {APP_LED_RED, 1, 50, 50, 4, 0, }, |
| {APP_LED_RED, 1, 100, 0, 0, 1, }, |
| {APP_LED_RED, 1, 0, 1000, 3, 1, }, |
| {APP_LED_RED, 1, 100, 100 , 1, 0, }, //5Hz for 3 seconds |
| |
| }; |
| |
| #endif |
| |
| void app_pairing_error(void) |
| { |
| device_led_setup(led_cfg[LED_PAIR_ERROR]); |
| } |
| |
| extern u32 keyScanLongPressTick; |
| |
| |
| #if (REMOTE_IR_ENABLE) |
| //ir key |
| #define TYPE_IR_SEND 1 |
| #define TYPE_IR_RELEASE 2 |
| |
| ///////////////////// key mode ////////////////////// |
| #define KEY_MODE_BLE 0 //ble key |
| #define KEY_MODE_IR 1 //ir key |
| |
| |
| _attribute_data_retention_ u8 *p_kb_map_ble; |
| _attribute_data_retention_ u8 *p_kb_map_ir; |
| _attribute_data_retention_ u8 *p_kb_map_normal; |
| |
| |
| void ir_dispatch(u8 type, u8 syscode ,u8 ircode){ |
| |
| if(!ir_hw_initialed){ |
| ir_hw_initialed = 1; |
| rc_ir_init(); |
| } |
| if(type == TYPE_IR_SEND){ |
| ir_send_ctrl.is_full_sequence = 0; |
| ir_nec_send(syscode,~(syscode),ircode); |
| |
| } |
| else if(type == TYPE_IR_RELEASE){ |
| ir_send_release(); |
| } |
| } |
| |
| |
| #endif |
| |
| |
| |
| #if (BLE_REMOTE_OTA_ENABLE) |
| #include "app_ota.h" |
| extern u8 mac_public[6]; |
| u8 app_enter_ota_mode(u8 *data) |
| { |
| printf("start data:"); |
| array_printf(data,4); |
| |
| u8 check_data[4]; |
| bls_ota_get_random(check_data); |
| |
| if(memcmp(check_data,data,4 )){ |
| |
| u8 report_data[3] ={CLIENT_REPORT_CMD, TYPE_OTA_RESULT, OTA_START_KEY_ERR}; |
| |
| bls_att_pushNotifyData(OTA_CMD_OUT_DP_H, report_data, 3); |
| printf("OTA_START_KEY_ERR\n"); |
| |
| return 1; |
| } |
| bls_pm_setSuspendMask (SUSPEND_DISABLE); |
| ota_flag = 1; |
| |
| //add user code |
| printf("ota start red led on\r\n"); |
| device_led_setup(led_cfg[LED_OTA_START]); |
| ota_is_working = 1; |
| bls_ota_setTimeout(90 * 1000 * 1000); //set OTA timeout 90 seconds |
| |
| return 0; |
| } |
| |
| /******************************************************************* |
| *** Use the following functions to modify various types of keys *** |
| *******************************************************************/ |
| /* |
| |
| //change authentication plaintext and plaintext key |
| void app_ota_get_plaintext_key(u8 *plaintext,u8 *cus_auth_key){ |
| |
| u8 auth_plaintext[16] = {'0','1','2','3','4','5','6','7','8','9','a','b',0x00,0x00,0x00,0x00,}; |
| u8 auth_key[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f',}; //OTA key; |
| |
| memcpy(plaintext,auth_plaintext,16); |
| memcpy(cus_auth_key,auth_key,16); |
| } |
| |
| void app_ota_get_fw_decryption_key(u8 *dec_key){ |
| |
| u8 key[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f',}; |
| memcpy(dec_key,key,16); |
| } |
| |
| //change ecdsa public key |
| void app_ota_get_ecdsa_pub_key(u8 *pub_key){ |
| u8 key[64] = {0x8d,0x82,0x79,0xc1,0xbb,0x22,0xe7,0x99,0xe6,0x97,0x49,0xf6,0xab,0x28,0x44,0x6d, |
| 0x9f,0x21,0xce,0x13,0x5b,0x43,0xfa,0x74,0x87,0xe2,0x96,0x49,0xcd,0xc8,0xdd,0xc3, |
| 0x92,0x6f,0x6e,0x3d,0x89,0xb0,0x5c,0xa7,0xf9,0xce,0xb7,0x38,0x97,0xa3,0xce,0x9a, |
| 0xae,0xaf,0x89,0xbe,0x8d,0x8d,0x03,0x1e,0x6b,0xb9,0x14,0x24,0xda,0x14,0x11,0xbe}; |
| memcpy(pub_key,key,64); |
| } |
| */ |
| |
| void app_ota_result(u8 result) |
| { |
| printf("google_ota_result result=%x\r\n",result); |
| u8 report_data[3]; |
| report_data[0] = CLIENT_REPORT_CMD; |
| report_data[1] = TYPE_OTA_RESULT; |
| report_data[2] = (u8)result; |
| if(device_in_connection_state) |
| { |
| u16 i = 0; |
| while(bls_att_pushNotifyData(OTA_CMD_OUT_DP_H, report_data, 3) && i < 2000){ |
| sleep_us(100); |
| i++; |
| } |
| |
| i = 0; |
| while(app_terminate(HCI_ERR_REMOTE_USER_TERM_CONN) && i < 2000){ |
| sleep_us(100); |
| i++; |
| } |
| |
| i = 0; |
| while(blc_ll_getTxFifoNumber() && i < 400){ |
| sleep_us(10000);//printf("waiting TX fifo is empty\n"); //waiting TX fifo is empty |
| i++; |
| } |
| } |
| if(result == 0) |
| { |
| printf("ota end red led off\r\n"); |
| device_led_setup(led_cfg[LED_OTA_END]); |
| printf("ota_suc and write_ana\r\n"); |
| analog_write(USED_DEEP_ANA_REG, analog_read(USED_DEEP_ANA_REG) | OTA_FLG); |
| printf("analog_read(USED_DEEP_ANA_REG)=%x\r\n",analog_read(USED_DEEP_ANA_REG)); |
| } |
| } |
| |
| extern u16 count_schedule_ota; |
| void app_schedule_ota(u8 *data) |
| { |
| //array_printf(data,4); |
| u16 count = (data[0]<<8) + data[1]; |
| |
| if(count ==0) |
| { |
| count_schedule_ota = 90; |
| |
| }else if(count >= 1440){ //24 hour |
| count_schedule_ota = 1440; |
| }else{ |
| count_schedule_ota = count; |
| } |
| printf("app_schedule_ota:0x%d\n",count); |
| |
| flag_schedule_ota = 0x55; |
| analog_write(DEEP_ANA_REG2, 0); |
| } |
| |
| int app_ota_timeoutcb(void) |
| { |
| printf("app_ota_timeoutcb\r\n"); |
| app_ota_terminate(OTA_TIMEOUT); |
| return -1; |
| } |
| |
| extern u8 google_ota_start_flag; |
| void app_ota_timeout(void) |
| { |
| app_pairing_error(); |
| blt_soft_timer_add(app_ota_timeoutcb, 1000000); |
| } |
| |
| void app_ota_status(u8 status) |
| { |
| if(device_in_connection_state == 0) return; |
| if(ota_is_working == 0) return; |
| ble_sts_t stat; |
| if((status == 0) && (ota_flag == 1)) |
| { |
| stat = app_ota_pause(); |
| ota_flag = 0; |
| printf("app_ota_pause stat=%x\r\n",stat); |
| } |
| |
| if((status == 1) && (ota_flag == 0)) |
| { |
| ble_sts_t stat; |
| stat = app_ota_continue(); |
| ota_flag = 1; |
| printf("app_ota_continue stat=%x\r\n",stat); |
| } |
| } |
| |
| void app_ota_slave_terminate(void) |
| { |
| printf("app_ota_slave_terminate\n"); |
| u8 report_data[3] = {CLIENT_REPORT_CMD, TYPE_OTA_RESULT, OTA_USER_TERMINATE}; |
| |
| u16 i = 0; |
| while(bls_att_pushNotifyData(OTA_CMD_OUT_DP_H, report_data, 3) && i < 2000){ |
| sleep_us(100); |
| i++; |
| } |
| } |
| |
| #define SCHE_OTA_1MIN 32000*60 |
| #define SCHE_OTA_1HOUR 32000*60*60 |
| void app_schedule_ota_enter_deep(void) |
| { |
| u8 sch_ota_timer[7]= {0,90,2,3,5,8,13}; |
| u8 data = analog_read(DEEP_ANA_REG2); |
| if(data == 0) |
| { |
| if((flag_schedule_ota == 0x55) && (device_timeout_state == 0x55)) |
| { |
| printf("sch ota first\r\n"); |
| analog_write(DEEP_ANA_REG2, 1); |
| cpu_long_sleep_wakeup_32k_rc(DEEPSLEEP_MODE,PM_WAKEUP_TIMER|PM_WAKEUP_PAD,count_schedule_ota*SCHE_OTA_1MIN); |
| } |
| else |
| { |
| printf("idle to sleep\r\n"); |
| cpu_sleep_wakeup(DEEPSLEEP_MODE, PM_WAKEUP_PAD, 0); |
| } |
| } |
| else |
| { |
| if(wakeup_src == 2) |
| { |
| data++; |
| printf("sch ota timer ++,data=%x\r\n",data); |
| } |
| else |
| printf("sch ota timer maintain\r\n"); |
| if(data >= 7) |
| { |
| printf("idle to sleep\r\n"); |
| analog_write(DEEP_ANA_REG2, 0); |
| cpu_sleep_wakeup(DEEPSLEEP_MODE, PM_WAKEUP_PAD, 0); |
| } |
| analog_write(DEEP_ANA_REG2, data); |
| if(data<7) |
| printf("sch ota data =%x,time =%x\r\n",data,sch_ota_timer[data]); |
| if(data == 1) |
| cpu_long_sleep_wakeup_32k_rc(DEEPSLEEP_MODE,PM_WAKEUP_TIMER|PM_WAKEUP_PAD,sch_ota_timer[data]*SCHE_OTA_1MIN); |
| else |
| cpu_long_sleep_wakeup_32k_rc(DEEPSLEEP_MODE,PM_WAKEUP_TIMER|PM_WAKEUP_PAD,sch_ota_timer[data]*SCHE_OTA_1HOUR); |
| } |
| } |
| |
| void app_schedule_ota_send_notify_to_continue_ota(void) |
| { |
| u8 dat[2] = {0}; |
| u8 report_data[4] = {CLIENT_REPORT_CMD,0x04,0x73,0x6f}; |
| u8 data = analog_read(DEEP_ANA_REG2); |
| |
| dat[0] = 0x73; |
| dat[1] = 0x6f; |
| if((wakeup_src == 2) && (data))//wake up for timer |
| { |
| printf("app_schedule_ota_send_notify_to_continue_ota\r\n"); |
| bls_att_pushNotifyData(HID_CONSUME_REPORT_INPUT_DP_H, dat, 2); |
| bls_att_pushNotifyData(OTA_CMD_OUT_DP_H, report_data, 4); |
| analog_write(DEEP_ANA_REG2, 0); |
| } |
| } |
| |
| void app_schedule_ota_wakeup_host(void) |
| { |
| u8 data = analog_read(DEEP_ANA_REG2); |
| u8 flag=0; |
| |
| if((wakeup_src == 2) && (data) && (power_down_flag == 2)) |
| { |
| flag = app_custom_is_enable_wakeup_key(); |
| if(flag) |
| { |
| printf("app_schedule_ota_wakeup_host\r\n"); |
| wakeup_key_send_flag = 2; |
| } |
| } |
| } |
| |
| #endif |
| |
| ///////////////////////////////////////////////////////////////////// |
| ///////////////////////////////////////////////////////////////////// |
| |
| |
| //This function process ... |
| void deep_wakeup_proc(void) |
| { |
| |
| #if(DEEPBACK_FAST_KEYSCAN_ENABLE) |
| //if deepsleep wakeup is wakeup by GPIO(key press), we must quickly scan this |
| //press, hold this data to the cache, when connection established OK, send to master |
| //deepsleep_wakeup_fast_keyscan |
| if(analog_read(USED_DEEP_ANA_REG) & CONN_DEEP_FLG){ |
| if(kb_scan_key (KB_NUMLOCK_STATUS_POWERON, 1) && kb_event.cnt){ |
| deepback_key_state = DEEPBACK_KEY_CACHE; |
| key_not_released = 1; |
| memcpy(&kb_event_cache,&kb_event,sizeof(kb_event)); |
| } |
| |
| analog_write(USED_DEEP_ANA_REG, analog_read(USED_DEEP_ANA_REG) & (~CONN_DEEP_FLG)); |
| } |
| #endif |
| } |
| |
| void deepback_pre_proc(int *det_key) |
| { |
| #if (DEEPBACK_FAST_KEYSCAN_ENABLE) |
| // to handle deepback key cache |
| if(!(*det_key) && deepback_key_state == DEEPBACK_KEY_CACHE && blc_ll_getCurrentState() == BLS_LINK_STATE_CONN \ |
| && clock_time_exceed(bls_ll_getConnectionCreateTime(), 25000)){ |
| |
| memcpy(&kb_event,&kb_event_cache,sizeof(kb_event)); |
| *det_key = 1; |
| |
| if(key_not_released || kb_event_cache.keycode[0] == VOICE){ //no need manual release |
| deepback_key_state = DEEPBACK_KEY_IDLE; |
| } |
| else{ //need manual release |
| deepback_key_tick = clock_time(); |
| deepback_key_state = DEEPBACK_KEY_WAIT_RELEASE; |
| } |
| } |
| #endif |
| } |
| |
| void deepback_post_proc(void) |
| { |
| #if (DEEPBACK_FAST_KEYSCAN_ENABLE) |
| //manual key release |
| if(deepback_key_state == DEEPBACK_KEY_WAIT_RELEASE && clock_time_exceed(deepback_key_tick,150000)){ |
| key_not_released = 0; |
| u8 key_buf[8] = {0}; |
| key_buf[2] = 0; |
| bls_att_pushNotifyData (HID_NORMAL_KB_REPORT_INPUT_DP_H, key_buf, 8); //release |
| deepback_key_state = DEEPBACK_KEY_IDLE; |
| } |
| #endif |
| } |
| #if BLE_AUDIO_ENABLE |
| |
| #include "application/audio/gl_audio.h" |
| |
| extern u8 app_audio_key_flags; |
| extern u8 htt_audio_model_key_press_flags; |
| |
| typedef enum{ |
| APP_ACCESSIBILITY_SHORTCUT_NONE=0, |
| APP_ACCESSIBILITY_SHORTCUT_PAIRING, |
| APP_ACCESSIBILITY_SHORTCUT_FACTORYRESET, |
| APP_ACCESSIBILITY_SHORTCUT_BUGREPORT, |
| APP_ACCESSIBILITY_SHORTCUT_DOWNBACK, |
| APP_ACCESSIBILITY_SHORTCUT_SINGLEKEY |
| }APP_Accessibility_Shortcut_Mode; |
| |
| |
| _attribute_data_retention_ u32 keyScanLongPressTick = 0; |
| _attribute_data_retention_ u32 LongPressTick = 0; |
| _attribute_data_retention_ APP_Accessibility_Shortcut_Mode Accessibility_Shortcut_Mode = APP_ACCESSIBILITY_SHORTCUT_NONE; |
| _attribute_data_retention_ u8 Accessibility_Shortcut_Flag = 0; |
| _attribute_data_retention_ u16 SpecialKey = 0; |
| |
| |
| int app_special_key_delay_timer(void) |
| { |
| printf("app_special_key_delay_timer\r\n"); |
| bls_att_pushNotifyData (HID_CONSUME_REPORT_INPUT_DP_H, (u8 *)&SpecialKey, 2); |
| return -1; |
| } |
| |
| int app_ir_bugreport_key_delay_timer(void) |
| { |
| printf("app_ir_bugreport_key_delay_timer\r\n"); |
| printf("\r\nir_key_value=%x\r\n",(u8)SpecialKey); |
| key_type = IR_KEY; |
| if(!ir_not_released){ |
| ir_dispatch(TYPE_IR_SEND, 0x88, (u8)SpecialKey); |
| ir_not_released = 1; |
| } |
| |
| if(key_not_released == 0) |
| { |
| if(ir_not_released)ir_not_released = 0; |
| if( ir_send_ctrl.is_sending) |
| { |
| ir_send_release(); |
| } |
| return -1; |
| } |
| if(key_not_released == 1) |
| return -1; |
| return -1; |
| } |
| |
| #if (STUCK_KEY_PROCESS_ENABLE) |
| extern u32 stuckkey_keypresstimer; |
| #endif |
| |
| extern void app_adv_indirect(void); |
| u8 app_repairing(void) |
| { |
| if(repairing_flag == 0x55) |
| { |
| printf("app_repairing\r\n"); |
| app_adv_indirect(); |
| repairing_flag = 0; |
| notify_get_rsp_en = 0; |
| return 1; |
| } |
| return 0; |
| } |
| |
| #define KEY_CACHE_TIMEOUT 8000000 |
| #define KEY_CACHE_MAX 22 |
| |
| _attribute_data_retention_ u8 app_key_store_count=0; |
| _attribute_data_retention_ u8 app_key_store_buffer[KEY_CACHE_MAX]={0}; |
| u8 app_keycache(u8 keyindex) |
| { |
| u8 i; |
| |
| u8 bond_number = blc_smp_param_getCurrentBondingDeviceNumber(); //get bonded device number |
| if(bond_number == 0) return 0; |
| if(en_powerkey_cache == 0) |
| { |
| if(keyindex == 0) return 0; |
| } |
| if(device_in_connection_state == 0) |
| { |
| if(app_key_store_count < KEY_CACHE_MAX) |
| { |
| for(i=0;i<app_key_store_count;i++) |
| { |
| if(app_key_store_buffer[i] == keyindex) |
| { |
| i = 0x55; |
| break; |
| } |
| } |
| if(i != 0x55) |
| app_key_store_buffer[app_key_store_count++] = keyindex; |
| } |
| else |
| { |
| app_key_store_count = KEY_CACHE_MAX; |
| for(i=0; i<KEY_CACHE_MAX-1; i++) |
| { |
| app_key_store_buffer[i] = app_key_store_buffer[i+1]; |
| } |
| app_key_store_buffer[i] = keyindex; |
| } |
| printf("app_keycache = \r\n"); |
| for(i=0;i<app_key_store_count;i++) |
| printf(" %x",app_key_store_buffer[i]); |
| return 0; |
| } |
| else if(device_in_connection_state && app_key_store_count != 0) |
| { |
| if(app_key_store_count < KEY_CACHE_MAX) |
| { |
| app_key_store_buffer[app_key_store_count++] = keyindex; |
| } |
| return 1; |
| } |
| else |
| { |
| return 0; |
| } |
| } |
| |
| |
| int app_cachekey_send_timer(void) |
| { |
| u8 i; |
| u8 key0; |
| u8 key_value; |
| u8 key_buf[8] = {0,0,0,0,0,0,0,0}; |
| u16 consumer_key[2]={0}; |
| |
| if(device_in_connection_state == 0) return 0; |
| if(app_key_store_count == 0) return -1; |
| printf("app_key_send_store,app_key_store_count=%x\r\n",app_key_store_count); |
| |
| key0 = app_key_store_buffer[0]; |
| printf("send cache key key=%x\r\n",key0); |
| { |
| programming_key_set(0); |
| key_value = p_kb_map_ble[key0]; |
| if(key_value >= CR_MEDIA_KEY_INDEX ) |
| { |
| if(key_value == CR_DASHBOARD) |
| { |
| consumer_key[0] = key_setting_or_noti[1]; |
| } |
| else if(key_value == CR_GUIDE) |
| { |
| consumer_key[0] = key_guide_or_livetv[1]; |
| } |
| else if(key_value == CR_SUBTITLE) |
| { |
| consumer_key[0] = key_subtitle_or_teletext[1]; |
| } |
| else |
| consumer_key[0] = vk_consumer_map[key_value-CR_MEDIA_KEY_INDEX]; |
| consumer_key[1] = 0; |
| printf("consume key=%x \r\n",consumer_key[0]); //down |
| bls_att_pushNotifyData (HID_CONSUME_REPORT_INPUT_DP_H, (u8 *)&consumer_key, 4); |
| consumer_key[0] = 0; //release |
| consumer_key[1] = 0; |
| bls_att_pushNotifyData (HID_CONSUME_REPORT_INPUT_DP_H, (u8 *)&consumer_key, 4); |
| |
| } |
| else |
| { |
| printf("KEYBOARD_KEY_key_value=%x \r\n",key_value); |
| key_buf[2] = key_value; //down |
| bls_att_pushNotifyData (HID_NORMAL_KB_REPORT_INPUT_DP_H, key_buf, 8); |
| |
| key_buf[2] = 0; //release |
| bls_att_pushNotifyData (HID_NORMAL_KB_REPORT_INPUT_DP_H, key_buf, 8); //release |
| } |
| } |
| |
| for(i=1; i<app_key_store_count; i++) |
| { |
| app_key_store_buffer[i-1] = app_key_store_buffer[i]; |
| } |
| app_key_store_count --; |
| if(app_key_store_count == 0) |
| return -1; |
| else |
| return 0; |
| } |
| |
| |
| void app_key_send_store(void) |
| { |
| u8 i; |
| u8 key0; |
| u8 key_value; |
| u8 key_buf[8] = {0,0,0,0,0,0,0,0}; |
| u16 consumer_key[2]={0}; |
| |
| if(app_key_store_count == 0) return; |
| if(device_in_connection_state == 0) return; |
| printf("app_key_send_store,app_key_store_count=%x\r\n",app_key_store_count); |
| |
| key0 = app_key_store_buffer[0]; |
| printf("send cache key key=%x\r\n",key0); |
| /* |
| if(ir_key_is_suppress(key0) == 0) |
| { |
| printf("is suppress\r\n"); |
| if(ir_fallback_send_key_code(key0,1)) |
| { |
| ir_fallback_send(0); //release |
| } |
| } |
| else |
| */ |
| { |
| programming_key_set(0); |
| key_value = p_kb_map_ble[key0]; |
| if(key_value >= CR_MEDIA_KEY_INDEX ) |
| { |
| if(key_value == CR_DASHBOARD) |
| { |
| consumer_key[0] = key_setting_or_noti[1]; |
| } |
| else if(key_value == CR_GUIDE) |
| { |
| consumer_key[0] = key_guide_or_livetv[1]; |
| } |
| else if(key_value == CR_SUBTITLE) |
| { |
| consumer_key[0] = key_subtitle_or_teletext[1]; |
| } |
| else |
| consumer_key[0] = vk_consumer_map[key_value-CR_MEDIA_KEY_INDEX]; |
| consumer_key[1] = 0; |
| printf("consume key=%x \r\n",consumer_key[0]); //down |
| bls_att_pushNotifyData (HID_CONSUME_REPORT_INPUT_DP_H, (u8 *)&consumer_key, 4); |
| consumer_key[0] = 0; //release |
| consumer_key[1] = 0; |
| bls_att_pushNotifyData (HID_CONSUME_REPORT_INPUT_DP_H, (u8 *)&consumer_key, 4); |
| |
| } |
| else |
| { |
| printf("KEYBOARD_KEY_key_value=%x \r\n",key_value); |
| key_buf[2] = key_value; //down |
| bls_att_pushNotifyData (HID_NORMAL_KB_REPORT_INPUT_DP_H, key_buf, 8); |
| |
| key_buf[2] = 0; //release |
| bls_att_pushNotifyData (HID_NORMAL_KB_REPORT_INPUT_DP_H, key_buf, 8); //release |
| } |
| } |
| |
| for(i=1; i<app_key_store_count; i++) |
| { |
| app_key_store_buffer[i-1] = app_key_store_buffer[i]; |
| } |
| app_key_store_count --; |
| } |
| const u8 navi_key_index_g10[4] = {1,4,15,18}; //left,right,up,down keyid in g10 |
| const u8 navi_key_index_g20[4] = {1,7,30,36}; //left,right,up,down keyid in g20 |
| |
| |
| u8 app_is_navi_key(u8 data0,u8 data1) |
| { |
| u8 flag[2]={5,5}; |
| |
| if(data0 == data1) return 0; |
| for(u8 i=0;i<4;i++) |
| { |
| if(device_type == REMOTE_G10) |
| { |
| if(data0 == navi_key_index_g10[i]) |
| flag[0] = i; |
| if(data1 == navi_key_index_g10[i]) |
| flag[1] = i; |
| } |
| else |
| { |
| if(data0 == navi_key_index_g20[i]) |
| flag[0] = i; |
| if(data1 == navi_key_index_g20[i]) |
| flag[1] = i; |
| } |
| } |
| if((flag[0]!=5) && (flag[1]!=5)) |
| return 1; |
| return 0; |
| } |
| |
| void app_release_hid_key(void) |
| { |
| u8 key_buf[8] = {0,0,0,0,0,0,0,0}; |
| u16 consumer_key[2]={0}; |
| u16 i=0; |
| |
| if(device_in_connection_state) |
| { |
| while(bls_att_pushNotifyData (HID_CONSUME_REPORT_INPUT_DP_H, (u8 *)&consumer_key, 4) && i<2000) |
| { |
| sleep_us(100); |
| i++; |
| } |
| i = 0; |
| while(bls_att_pushNotifyData (HID_NORMAL_KB_REPORT_INPUT_DP_H, key_buf, 8) && i<2000) |
| { |
| sleep_us(100); |
| i++; |
| } |
| i = 0; |
| while(app_terminate(HCI_ERR_REMOTE_USER_TERM_CONN) && i < 2000) |
| { |
| sleep_us(100); |
| i++; |
| } |
| i =0; |
| while(blc_ll_getTxFifoNumber() && i<400) |
| { |
| sleep_us(1000); |
| i++; |
| } |
| printf("app_release_hid_key\r\n"); |
| } |
| |
| } |
| void comb_key_stop_ir(void) |
| { |
| blt_soft_timer_delete(app_ir_bugreport_key_delay_timer); |
| if(device_in_connection_state == 0) |
| { |
| if(ir_not_released)ir_not_released = 0; |
| if( ir_send_ctrl.is_sending) |
| { |
| ir_send_release(); |
| } |
| } |
| else |
| { |
| //factory reset and key mute is ir programmed |
| if(ir_send_ctrl.is_sending) |
| { |
| printf("comb_key_stop_ir and ir release\r\n"); |
| programming_key_set(0); |
| ir_send_release(); |
| } |
| } |
| } |
| |
| #define FACTORY_RESET_TIMEOUT 100000 |
| |
| _attribute_data_retention_ u8 factory_reset_flag = 0; |
| _attribute_data_retention_ u8 factory_reset_temi_conn_flag = 0; |
| _attribute_data_retention_ u8 factory_reset_timer_count = 0; |
| |
| int app_factory_reset_timer(void) |
| { |
| u8 bond_number; |
| u16 i=0; |
| printf("app_factory_reset_timer\r\n"); |
| if(device_in_connection_state) |
| { |
| printf("app_factory_reset_timer_google_voice_ctl=%x\r\n",google_voice_ctl); |
| if(((google_voice_ctl & FLAG_AUDIO_CLOSE) == 0) || (ota_is_working)) |
| { |
| if(ota_is_working) |
| { |
| app_ota_slave_terminate(); |
| device_led_off(APP_LED_RED); |
| } |
| if(factory_reset_temi_conn_flag == 0) |
| { |
| i = 0; |
| while(app_terminate(HCI_ERR_REMOTE_USER_TERM_CONN) && i < 2000){ |
| sleep_us(100); |
| i++; |
| } |
| } |
| else |
| { |
| if(blc_ll_getTxFifoNumber()) |
| { |
| factory_reset_temi_conn_flag++; |
| if(factory_reset_temi_conn_flag < 20) |
| { |
| return 0; |
| } |
| } |
| } |
| } |
| else |
| { |
| factory_reset_timer_count++; |
| if(factory_reset_timer_count < 20) |
| { |
| return 0; |
| } |
| } |
| } |
| |
| ir_flash_factory(); |
| flash_erase_sector(MAC_DATA_SECT_ADDR); |
| bond_number = blc_smp_param_getCurrentBondingDeviceNumber(); //get bonded device number |
| printf("bond_number=%x\r\n",bond_number); |
| if(bond_number) |
| { |
| printf("delete bond info\r\n"); |
| bls_smp_param_deleteByIndex(0); |
| } |
| factory_reset_flag = 0; |
| factory_reset_temi_conn_flag = 0; |
| factory_reset_timer_count = 0; |
| google_voice_ctl = 0; |
| ota_is_working = 0; |
| return -1; |
| } |
| |
| void app_mic_led(u8 en) |
| { |
| if(audio_start_reason == REASON_PTT) |
| { |
| if(en) |
| { |
| device_led_setup(led_cfg[LED_SHINE_PTT]); |
| } |
| else |
| { |
| if(factory_reset_flag == 0) |
| { |
| device_led_setup(led_cfg[en ? 1 : 2]); |
| } |
| } |
| } |
| else |
| { |
| if(en) |
| { |
| device_led_setup(led_cfg[en ? 1 : 2]); |
| } |
| else |
| { |
| if(factory_reset_flag == 0) |
| { |
| device_led_setup(led_cfg[en ? 1 : 2]); |
| } |
| } |
| } |
| } |
| |
| void app_keypress_led(u8 ir_key) |
| { |
| if(lowbat == 0x55) |
| { |
| printf("low bat\r\n"); |
| device_led_setup(led_cfg[LED_SHINE_LOWBAT]); |
| if((is_pairing_mode == 0) && (is_reconn_mode == 0) && (ui_mic_enable == 0)) |
| { |
| if(device_in_connection_state == 1) |
| { |
| device_led_setup(led_cfg[LED_SHINE_FAST]); |
| } |
| } |
| return; |
| } |
| else |
| { |
| if((is_pairing_mode == 0) && (is_reconn_mode == 0) && (ui_mic_enable == 0)) |
| { |
| if(device_in_connection_state == 1) |
| { |
| device_led_setup(led_cfg[LED_SHINE_FAST]); |
| } |
| } |
| if((ota_is_working == 0) && (device_in_connection_state == 0)) |
| { |
| device_led_setup(led_cfg[LED_KEYPRESS]); |
| } |
| } |
| if(ir_key) |
| { |
| if((is_pairing_mode == 0) && (ota_is_working == 0) && (ui_mic_enable == 0)) |
| { |
| printf("ir db key press\r\n"); |
| device_led_setup(led_cfg[LED_SHINE_FAST]); |
| device_led_setup(led_cfg[LED_KEYPRESS]); |
| } |
| } |
| } |
| |
| void app_connect_led(void) |
| { |
| device_led_setup(led_cfg[LED_SHINE_SUCCESS]); |
| } |
| |
| void app_pairing_led(void) |
| { |
| device_led_setup(led_cfg[LED_SHINE_PAIRING]); |
| } |
| |
| void app_accessibility_short_key_to_single_key(void) |
| { |
| if(Accessibility_Shortcut_Mode != APP_ACCESSIBILITY_SHORTCUT_NONE) |
| { |
| printf("app_accessibility_short_key_to_single_key\r\n"); |
| Accessibility_Shortcut_Mode = APP_ACCESSIBILITY_SHORTCUT_SINGLEKEY; |
| } |
| if((is_pairing_mode == 0)) |
| { |
| printf("app_accessibility_short_key_to_single_key_close led\r\n"); |
| device_led_off(APP_LED_GREEN); |
| } |
| } |
| |
| int app_poweron_timeout(void) |
| { |
| u8 bond_number = blc_smp_param_getCurrentBondingDeviceNumber(); |
| printf("app_poweron_timeout\r\n"); |
| if(bond_number == 0) |
| { |
| is_pairing_mode = 0x55; |
| notify_get_rsp_en = 1; |
| app_pairing_led(); |
| app_adv_indirect(); |
| } |
| |
| return -1; |
| } |
| |
| |
| extern void advertise_tick_retime(void); |
| void key_change_proc(void) |
| { |
| latest_user_event_tick = clock_time(); //record latest key change time |
| |
| u8 key0 = kb_event.keycode[0]; |
| u8 key1 = kb_event.keycode[1]; |
| u8 key_value; |
| u8 key_buf[8] = {0,0,0,0,0,0,0,0}; |
| u16 consumer_key[2]={0}; |
| |
| key_not_released = 1; |
| if (kb_event.cnt == 2) //two key press, do not process |
| { |
| //retime |
| advertise_tick_retime(); |
| if(is_pairing_mode) return; |
| Accessibility_Shortcut_Flag = 0x55; |
| #if (STUCK_KEY_PROCESS_ENABLE) |
| stuckkey_keypresstimer = clock_time() | 1; |
| #endif |
| if (((key0 == comb_key_keyid[0]) && (key1 == comb_key_keyid[1])) || ((key0 == comb_key_keyid[1]) && (key1 == comb_key_keyid[0]))) //Pairing Mode back+home |
| { |
| printf("pair start\r\n"); |
| comb_key_stop_ir(); |
| blt_soft_timer_delete(app_special_key_delay_timer); |
| //in voice mode need disable enter pairing mode |
| if(ui_mic_enable) |
| { |
| return; |
| } |
| if(lowbat == 0) |
| { |
| device_led_setup(led_cfg[LED_AUDIO_ON]); |
| } |
| keyScanLongPressTick = clock_time() | 1; //none zero |
| LongPressTick = 4000000; |
| Accessibility_Shortcut_Mode = APP_ACCESSIBILITY_SHORTCUT_PAIRING; |
| } |
| else if (((key0 == comb_key_keyid[2]) && (key1 == comb_key_keyid[3])) || ((key0 == comb_key_keyid[3]) && (key1 == comb_key_keyid[2]))) //Factory Reset Mode center+mute |
| { |
| printf("Factory Reset Mode start\r\n"); |
| comb_key_stop_ir(); |
| device_led_off(APP_LED_GREEN); |
| if(lowbat == 0) |
| { |
| device_led_setup(led_cfg[LED_AUDIO_ON]); |
| } |
| keyScanLongPressTick = clock_time() | 1; //none zero |
| LongPressTick = 4000000; |
| Accessibility_Shortcut_Mode = APP_ACCESSIBILITY_SHORTCUT_FACTORYRESET; |
| } |
| else if (((key0 == comb_key_keyid[0]) && (key1 == comb_key_keyid[2])) || ((key0 == comb_key_keyid[2]) && (key1 == comb_key_keyid[0]))) //Bug report back+center |
| { |
| printf("bug report start\r\n"); |
| comb_key_stop_ir(); |
| device_led_setup(led_cfg[LED_AUDIO_ON]); |
| keyScanLongPressTick = clock_time() | 1; //none zero |
| LongPressTick = 1000000; |
| Accessibility_Shortcut_Mode = APP_ACCESSIBILITY_SHORTCUT_BUGREPORT; |
| } |
| else |
| { |
| if (((key0 == comb_key_keyid[0]) && (key1 == comb_key_keyid[7])) || ((key0 == comb_key_keyid[7]) && (key1 == comb_key_keyid[0]))) // back+down |
| { |
| printf("back+dwon\r\n"); |
| if(device_in_connection_state) |
| { |
| keyScanLongPressTick = clock_time() | 1; //none zero |
| LongPressTick = 1000000; |
| Accessibility_Shortcut_Mode = APP_ACCESSIBILITY_SHORTCUT_DOWNBACK; |
| return; |
| } |
| } |
| if(device_in_connection_state == 0) |
| { |
| if(app_is_navi_key(key0,key1) == 0) |
| { |
| printf(" stop double key in ir mode\r\n"); |
| blt_soft_timer_delete(app_ir_bugreport_key_delay_timer); |
| printf("ir_send_ctrl.is_sending =%x\r\n",ir_send_ctrl.is_sending); |
| if(ir_send_ctrl.is_sending) |
| { |
| key_type = IR_KEY; |
| ir_send_release(); |
| } |
| } |
| else |
| { |
| printf("double key is navi in ir mode\r\n"); |
| if(ir_send_ctrl.is_sending == IR_SENDING_NONE) |
| { |
| if(key0 == comb_key_keyid[4]) //setting |
| key_value = key_setting_or_noti[0]; |
| else if(key0 == comb_key_keyid[5]) //guide |
| key_value = key_guide_or_livetv[0]; |
| else if(key0 == comb_key_keyid[6]) //subtitle |
| key_value = key_subtitle_or_teletext[0]; |
| else |
| key_value = p_kb_map_ir[key0]; |
| key_type = IR_KEY; |
| ir_dispatch(TYPE_IR_SEND, 0x88, key_value); |
| if(ir_not_released == 0) ir_not_released = 1; |
| } |
| } |
| } |
| else |
| { |
| if(app_is_navi_key(key0,key1) == 0) |
| { |
| printf(" stop double key in rf mode\r\n"); |
| if(key_type == CONSUMER_KEY) |
| { |
| consumer_key[0] = 0; |
| consumer_key[1] = 0; |
| bls_att_pushNotifyData (HID_CONSUME_REPORT_INPUT_DP_H, (u8 *)&consumer_key, 4); |
| } |
| else if(key_type == KEYBOARD_KEY) |
| { |
| key_buf[2] = 0; |
| bls_att_pushNotifyData (HID_NORMAL_KB_REPORT_INPUT_DP_H, key_buf, 8); //release |
| } |
| } |
| else |
| { |
| printf("double key is navi in rf mode,key0=%x,key1=%x\r\n",key0,key1); |
| u16 comb_key[2]; |
| comb_key[0] = vk_consumer_map[p_kb_map_ble[key0]-CR_MEDIA_KEY_INDEX]; |
| comb_key[1] = vk_consumer_map[p_kb_map_ble[key1]-CR_MEDIA_KEY_INDEX]; |
| bls_att_pushNotifyData (HID_CONSUME_REPORT_INPUT_DP_H, (u8 *)&comb_key, 4); |
| } |
| } |
| } |
| } |
| else if(kb_event.cnt == 1) |
| { |
| //retime |
| advertise_tick_retime(); |
| |
| printf("key_id=%x\r\n",key0); |
| |
| #if (STUCK_KEY_PROCESS_ENABLE) |
| stuckkey_keypresstimer = clock_time() | 1; |
| #endif |
| |
| if(device_in_connection_state == 0) |
| { |
| u8 bond_number = blc_smp_param_getCurrentBondingDeviceNumber(); |
| if(bond_number == 1) |
| { |
| if(app_custom_is_wakeup_key(key0) == 1) |
| { |
| if(wakeup_key_send_flag == 0) |
| { |
| extern u8 wakeup_key_keycount; |
| wakeup_key_keycount++; |
| printf("app_send_wakeup_loop 5s start wakeup_key_keycount=%x\r\n",wakeup_key_keycount); |
| write_wakeup_keyindex_info(wakeup_key_keycount); |
| wakeup_key_send_flag = 1; |
| wakeup_key_keyid = key0; |
| advertise_begin_tick = 0; |
| wakeup_packet_format = 0x55; |
| } |
| } |
| } |
| } |
| |
| #if (BLE_AUDIO_ENABLE) |
| if(device_in_connection_state) |
| { |
| if (key0 == VOICE) |
| { |
| if(google_voice_ctl & FLAG_NOTIFY_AUDIO_DATA) return; |
| printf("CONSUMER_KEY\n"); |
| key_type = VOICE_KEY; |
| google_voice_start(); |
| return; |
| } |
| } |
| #endif |
| active_mic_open(); |
| key_type = IR_KEY; |
| |
| if(ir_key_is_suppress(key0) == 0) |
| { |
| //printf("is suppress\r\n"); |
| app_keypress_led(1); |
| if(ir_fallback_send_key_code(key0,1)) |
| { |
| if(!ir_not_released) |
| ir_not_released = 1; |
| return; |
| } |
| } |
| app_keypress_led(0); |
| if(app_keycache(key0) == 1) |
| { |
| return; |
| } |
| programming_key_set(0); |
| if(device_in_connection_state) |
| { |
| key_value = p_kb_map_ble[key0]; |
| printf("key_value=%x\r\n",key_value); |
| |
| if(key_value >= CR_MEDIA_KEY_INDEX ) |
| { |
| key_type = CONSUMER_KEY; |
| if(key_value == CR_DASHBOARD) |
| { |
| consumer_key[0] = key_setting_or_noti[1]; |
| } |
| else if(key_value == CR_GUIDE) |
| { |
| consumer_key[0] = key_guide_or_livetv[1]; |
| } |
| else if(key_value == CR_SUBTITLE) |
| { |
| consumer_key[0] = key_subtitle_or_teletext[1]; |
| } |
| else |
| consumer_key[0] = vk_consumer_map[key_value-CR_MEDIA_KEY_INDEX]; |
| consumer_key[1] = 0; |
| printf("consume key=%x \r\n",consumer_key[0]); |
| if((key0 == comb_key_keyid[0]) || (key0 == comb_key_keyid[1])) //back or home key |
| { |
| SpecialKey = consumer_key[0]; |
| blt_soft_timer_add(app_special_key_delay_timer, 80000); |
| return; |
| } |
| bls_att_pushNotifyData (HID_CONSUME_REPORT_INPUT_DP_H, (u8 *)&consumer_key, 4); |
| if(consumer_key[0] == G00GLE_MKEY_CENTER) |
| { |
| google_voice_dpad_select(); |
| } |
| } |
| else |
| { |
| //printf("KEYBOARD_KEY_key_value=%x \r\n",key_value); |
| |
| key_type = KEYBOARD_KEY; |
| key_buf[2] = key_value; |
| bls_att_pushNotifyData (HID_NORMAL_KB_REPORT_INPUT_DP_H, key_buf, 8); |
| } |
| |
| } |
| else |
| { |
| if(key0 == VOICE) |
| key_value = 0x46; |
| else if(key0 == comb_key_keyid[4]) |
| key_value = key_setting_or_noti[0]; |
| else if(key0 == comb_key_keyid[5]) |
| key_value = key_guide_or_livetv[0]; |
| else if(key0 == comb_key_keyid[6]) |
| key_value = key_subtitle_or_teletext[0]; |
| else |
| key_value = p_kb_map_ir[key0]; |
| if((key_value == IR_BACK) &&(is_pairing_mode == 0x55)) |
| { |
| printf("back key, stop adv\r\n"); |
| device_led_off(APP_LED_GREEN); |
| bls_ll_setAdvEnable(0); |
| is_pairing_mode = 0; |
| is_reconn_mode = 0; |
| app_enter_deep_timeset(); |
| u8 bond_number = blc_smp_param_getCurrentBondingDeviceNumber(); //get bonded device number |
| printf("bond_number_1=%x\r\n",bond_number); |
| } |
| if((key0 == comb_key_keyid[0]) || (key0 == comb_key_keyid[2])) //center or back |
| { |
| SpecialKey = key_value; |
| blt_soft_timer_add(app_ir_bugreport_key_delay_timer, 80000); |
| return; |
| } |
| printf("\r\nir_key_value=%x\r\n",key_value); |
| key_type = IR_KEY; |
| if(!ir_not_released){ |
| printf("ir_dispatch send\r\n"); |
| ir_dispatch(TYPE_IR_SEND, 0x88, key_value); |
| ir_not_released = 1; |
| } |
| } |
| |
| } |
| else //kb_event.cnt == 0, key release |
| { |
| printf("key release\r\n"); |
| advertise_tick_retime(); |
| if((audio_start_reason == REASON_HTT) && (google_voice_ctl & FLAG_NOTIFY_AUDIO_DATA)){ |
| printf("key release_audio_start_reason:0x%x\n",audio_start_reason); |
| google_voice_ctl |= FLAG_AUDIO_CLOSE; |
| audio_stop_reason = REASON_RELEASE_HTT; |
| audio_start_reason = 0; |
| } |
| key_not_released = 0; |
| keyScanLongPressTick = 0; |
| LongPressTick = 0; |
| #if (STUCK_KEY_PROCESS_ENABLE) |
| stuckkey_keypresstimer = 0; |
| #endif |
| if(is_programming_key_send() == 1) |
| { |
| printf("key up\r\n"); |
| ir_fallback_send(0); |
| } |
| programming_key_set(0); |
| printf("key_type=%x\r\n",key_type); |
| if(key_type == CONSUMER_KEY) |
| { |
| consumer_key[0] = 0; |
| consumer_key[1] = 0; |
| bls_att_pushNotifyData (HID_CONSUME_REPORT_INPUT_DP_H, (u8 *)&consumer_key, 4); |
| } |
| else if(key_type == KEYBOARD_KEY) |
| { |
| key_buf[2] = 0; |
| bls_att_pushNotifyData (HID_NORMAL_KB_REPORT_INPUT_DP_H, key_buf, 8); //release |
| } |
| |
| #if (REMOTE_IR_ENABLE) |
| else if(key_type == IR_KEY) |
| { |
| if(ir_not_released){ |
| ir_not_released = 0; |
| if(ir_send_ctrl.is_sending) |
| { |
| ir_dispatch(TYPE_IR_RELEASE, 0, 0); //release |
| } |
| ir_repeat_delay_release_time(); |
| } |
| } |
| #endif |
| Accessibility_Shortcut_Flag = 0; |
| } |
| |
| |
| } |
| |
| void app_factory_reset(void) |
| { |
| u8 audio_open=0; |
| |
| printf("Factory Reset Mode ongoning\r\n"); |
| if(lowbat == 0x55) |
| { |
| return; |
| } |
| |
| //global vari |
| factory_reset_flag = 0x55; |
| is_reconn_mode = 0; |
| is_pairing_mode = 0; |
| |
| flag_ccc_data = 0; |
| atv_char_ctl_ccc = 0; |
| atv_char_rx_ccc = 0; |
| write_ccc_info(&flag_ccc_data); |
| //led |
| device_led_setup(led_cfg[LED_SHINE_SUCCESS]); |
| |
| //ir |
| write_ir_key_event_notify(0); |
| ir_table_init(); |
| analog_write(DEEP_ANA_REG2, 0); |
| bls_ll_setAdvEnable(0); |
| if(device_in_connection_state) |
| { |
| printf("Accessibility_Shortcut_Mode=%x\r\n",Accessibility_Shortcut_Mode); |
| if(ui_mic_enable) |
| { |
| audio_open = 1; |
| extern u8 app_audio_key_stop(u8 reason); |
| app_audio_key_stop(REASON_OTHERS); |
| } |
| } |
| extern void app_enter_deep_timeset(void); |
| app_enter_deep_timeset(); |
| if(audio_open) |
| blt_soft_timer_add(app_factory_reset_timer, FACTORY_RESET_TIMEOUT); |
| else |
| app_factory_reset_timer(); |
| |
| } |
| |
| #define GPIO_WAKEUP_KEYPROC_CNT 3 |
| |
| |
| _attribute_data_retention_ static int gpioWakeup_keyProc_cnt = 0; |
| _attribute_data_retention_ static u32 keyScanTick = 0; |
| |
| void proc_keyboard (u8 e, u8 *p, int n) |
| { |
| u16 consumer_key[2]; |
| //when key press gpio wakeup suspend, proc keyscan at least GPIO_WAKEUP_KEYPROC_CNT times |
| //regardless of 8000 us interval |
| if(e == BLT_EV_FLAG_GPIO_EARLY_WAKEUP){ |
| gpioWakeup_keyProc_cnt = GPIO_WAKEUP_KEYPROC_CNT; |
| } |
| else if(gpioWakeup_keyProc_cnt){ |
| gpioWakeup_keyProc_cnt --; |
| } |
| |
| |
| if(gpioWakeup_keyProc_cnt || clock_time_exceed(keyScanTick, 8000)){ |
| keyScanTick = clock_time(); |
| } |
| else{ |
| return; |
| } |
| |
| kb_event.keycode[0] = 0; |
| int det_key = kb_scan_key (0, 1); |
| |
| |
| #if(DEEPBACK_FAST_KEYSCAN_ENABLE) |
| if(deepback_key_state != DEEPBACK_KEY_IDLE){ |
| deepback_pre_proc(&det_key); |
| } |
| #endif |
| |
| |
| if (det_key){ |
| #if (MP_TEST_MODE) |
| if (test_get_mode() == MODE_TEST) test_proc_key(); |
| else |
| #endif |
| key_change_proc(); |
| } |
| |
| #if(DEEPBACK_FAST_KEYSCAN_ENABLE) |
| if(deepback_key_state != DEEPBACK_KEY_IDLE){ |
| deepback_post_proc(); |
| } |
| #endif |
| |
| if((keyScanLongPressTick == 0) && (Accessibility_Shortcut_Mode != APP_ACCESSIBILITY_SHORTCUT_NONE)) |
| { |
| printf("stop led\r\n"); |
| device_led_off(APP_LED_GREEN); |
| Accessibility_Shortcut_Mode = APP_ACCESSIBILITY_SHORTCUT_NONE; |
| } |
| |
| if(keyScanLongPressTick && clock_time_exceed(keyScanLongPressTick, LongPressTick)) |
| { |
| keyScanLongPressTick = 0; |
| advertise_tick_retime(); |
| printf("Accessibility_Shortcut timeout and Accessibility_Shortcut_Mode=%x\r\n",Accessibility_Shortcut_Mode); |
| if(Accessibility_Shortcut_Mode == APP_ACCESSIBILITY_SHORTCUT_SINGLEKEY) return; |
| if(Accessibility_Shortcut_Mode == APP_ACCESSIBILITY_SHORTCUT_PAIRING) |
| { |
| printf("trigger pair\r\n"); |
| if(lowbat == 0x55) |
| { |
| return; |
| } |
| device_led_setup(led_cfg[LED_SHINE_PAIRING]); |
| is_pairing_mode = 0x55; |
| if(is_reconn_mode) |
| is_reconn_mode = 0; |
| notify_get_rsp_en = 1; |
| if( device_in_connection_state == 0) |
| { |
| ir_table_init(); |
| ir_flash_set_flag(0); |
| app_set_adv_interval_downgrade_indirect(); |
| extern void app_adv_indirect(void); |
| app_adv_indirect(); |
| } |
| else |
| { |
| if(ota_is_working) |
| { |
| app_ota_slave_terminate(); |
| device_led_off(APP_LED_RED); |
| } |
| printf("re-pairing \r\n"); |
| u16 i=0; |
| while(app_terminate(HCI_ERR_REMOTE_USER_TERM_CONN) && i < 2000){ |
| sleep_us(100); |
| i++; |
| } |
| repairing_flag = 0x55; |
| } |
| } |
| else if(Accessibility_Shortcut_Mode == APP_ACCESSIBILITY_SHORTCUT_FACTORYRESET) |
| { |
| app_factory_reset(); |
| } |
| else if(Accessibility_Shortcut_Mode == APP_ACCESSIBILITY_SHORTCUT_BUGREPORT) |
| { |
| printf("APP_ACCESSIBILITY_SHORTCUT_BUGREPORT ongoning\r\n"); |
| device_led_setup(led_cfg[LED_SHINE_SUCCESS]); |
| if(device_in_connection_state == 0) |
| { |
| key_type = IR_KEY; |
| if(!ir_not_released){ |
| ir_dispatch(TYPE_IR_SEND, 0x88, 0x96); |
| ir_not_released = 1; |
| } |
| } |
| else |
| { |
| consumer_key[0] = G00GLE_MKEY_BACK; |
| consumer_key[1] = G00GLE_MKEY_CENTER; |
| bls_att_pushNotifyData (HID_CONSUME_REPORT_INPUT_DP_H, (u8 *)&consumer_key, 4); |
| } |
| } |
| else if(Accessibility_Shortcut_Mode == APP_ACCESSIBILITY_SHORTCUT_DOWNBACK) |
| { |
| printf("APP_ACCESSIBILITY_SHORTCUT_DOWNBACK ongoning\r\n"); |
| device_led_setup(led_cfg[LED_SHINE_SUCCESS]); |
| if(device_in_connection_state) |
| { |
| consumer_key[0] = G00GLE_MKEY_BACK; |
| consumer_key[1] = G00GLE_MKEY_DN; |
| bls_att_pushNotifyData (HID_CONSUME_REPORT_INPUT_DP_H, (u8 *)&consumer_key, 4); |
| } |
| } |
| Accessibility_Shortcut_Mode = APP_ACCESSIBILITY_SHORTCUT_NONE; |
| } |
| |
| //app_key_send_store(); |
| } |
| #endif |
| |
| extern u32 scan_pin_need; |
| |
| void app_ui_init_normal(void) |
| { |
| kb_wake_config(); |
| |
| bls_app_registerEventCallback (BLT_EV_FLAG_GPIO_EARLY_WAKEUP, &proc_keyboard); |
| |
| #if (BLE_AUDIO_ENABLE) |
| #if (BLE_DMIC_ENABLE) |
| dmic_gpio_reset(); |
| #else |
| amic_gpio_reset(); |
| #endif |
| #endif |
| |
| |
| #if (BLT_APP_LED_ENABLE) |
| device_led_init(); //LED initialization |
| device_led_off(APP_LED_RED); |
| if((analog_read(USED_DEEP_ANA_REG) & POWER_ON_FLG) == 0) |
| { |
| device_led_setup(led_cfg[LED_POWER_ON]); //only poweron |
| } |
| #endif |
| analog_write(USED_DEEP_ANA_REG, analog_read(USED_DEEP_ANA_REG) | POWER_ON_FLG); |
| |
| #if (REMOTE_IR_ENABLE) |
| user_key_mode = analog_read(USED_DEEP_ANA_REG) & IR_MODE_DEEP_FLG ? KEY_MODE_IR : KEY_MODE_BLE; |
| #endif |
| |
| |
| #if (BLT_TEST_SOFT_TIMER_ENABLE) |
| blt_soft_timer_init(); |
| |
| if( |
| (power_down_flag == 1) |
| #if (MP_TEST_MODE) |
| && (test_get_mode() != MODE_TEST) |
| #endif |
| ) |
| { |
| blt_soft_timer_add(app_poweron_timeout, 1000000); |
| } |
| #endif |
| |
| } |
| |
| |
| |
| void app_ui_init_deepRetn(void) |
| { |
| kb_wake_config(); |
| |
| #if (BLE_AUDIO_ENABLE) |
| #if (BLE_DMIC_ENABLE) |
| dmic_gpio_reset(); |
| #else |
| amic_gpio_reset(); |
| #endif |
| #endif |
| |
| #if (BLT_APP_LED_ENABLE) |
| device_led_init(); //LED initialization |
| #endif |
| |
| #if (REMOTE_IR_ENABLE) |
| user_key_mode = analog_read(USED_DEEP_ANA_REG) & IR_MODE_DEEP_FLG ? KEY_MODE_IR : KEY_MODE_BLE; |
| #endif |
| } |
| |
| |
| |
| extern u16 atv_char_ctl_ccc; |
| extern u16 atv_char_rx_ccc; |
| |
| int att_ccc_control(void* p){ |
| printf("att_ccc_control\n"); |
| rf_packet_att_data_t *pw = (rf_packet_att_data_t *)p; |
| u16 handle = (pw->hh << 8) + pw->hl; |
| |
| u16 data = (pw->dat[1] << 8) + pw->dat[0]; |
| |
| array_printf(pw->dat,(pw->l2cap - 3)); |
| |
| u8 save_to_flash = 1; |
| |
| switch(handle){ |
| case AUDIO_GOOGLE_RX_CCC_H: |
| { |
| printf("AUDIO_GOOGLE_RX_CCC_H\n"); |
| |
| atv_char_rx_ccc = data; |
| |
| if(data){ |
| if(flag_ccc_data & FLAG_GOOGLE_RX_CCC){ |
| save_to_flash = 0; |
| }else{ |
| flag_ccc_data |= FLAG_GOOGLE_RX_CCC; |
| } |
| |
| }else{ |
| if(flag_ccc_data & FLAG_GOOGLE_RX_CCC){ |
| flag_ccc_data &= ~FLAG_GOOGLE_RX_CCC; |
| }else{ |
| save_to_flash = 0; |
| } |
| } |
| break; |
| } |
| case AUDIO_GOOGLE_CTL_CCC_H: |
| { |
| printf("AUDIO_GOOGLE_CTL_CCC_H\n"); |
| |
| atv_char_ctl_ccc = data; |
| |
| if(data){ |
| if(flag_ccc_data & FLAG_GOOGLE_CTL_CCC){ |
| save_to_flash = 0; |
| }else{ |
| flag_ccc_data |= FLAG_GOOGLE_CTL_CCC; |
| } |
| |
| }else{ |
| if(flag_ccc_data & FLAG_GOOGLE_CTL_CCC){ |
| flag_ccc_data &= ~FLAG_GOOGLE_CTL_CCC; |
| }else{ |
| save_to_flash = 0; |
| } |
| } |
| break; |
| } |
| case OTA_CMD_OUT_CCC_H: |
| { |
| printf("OTA_CMD_OUT_CCC_H\n"); |
| |
| extern u16 my_Otaccc; |
| my_Otaccc = data; |
| |
| save_to_flash = 0; |
| break; |
| } |
| default: |
| { |
| save_to_flash = 0; |
| break; |
| } |
| } |
| |
| if(save_to_flash){ |
| //save ccc data to flash |
| write_ccc_info(&flag_ccc_data); |
| } |
| |
| return 0; |
| } |
| |
| u8 app_is_key_released(void) |
| { |
| return key_not_released; |
| } |
| |
| |