| /* |
| ******************************************************************************* |
| * |
| * @file rc_mmi.c |
| * |
| * @brief MMI (Man Machine Interface) of Atmosic remote controller reference design. |
| * |
| * Copyright (C) Atmosic 2020-2022 |
| * |
| ******************************************************************************* |
| */ |
| |
| #include <inttypes.h> |
| #include "app_config.h" |
| #include "rc_hogp.h" |
| #include "rc_gap.h" |
| #include "led_blink.h" |
| #include "app_bass.h" |
| #ifdef CFG_VOHID |
| #include "rc_hidau.h" |
| #else |
| #include "rc_atvv.h" |
| #endif |
| #include "rc_ir.h" |
| #include "rc_pdm.h" |
| #include "rc_mmi.h" |
| #include "rc_mmi_vkey.h" |
| #include "led_blink.h" |
| #include "atm_gpio.h" |
| #include "atm_debug.h" |
| #include "atm_asm.h" |
| #include "co_utils.h" |
| #include "atm_pm.h" |
| #ifdef AUTO_TEST |
| #include "uart_stdout.h" |
| #endif |
| #include "gadc.h" |
| #include "rc_keycode.h" |
| #include "app_batt.h" |
| #ifdef CFG_USB_DET |
| #include "interrupt.h" |
| #include "pinmux.h" |
| #endif |
| #ifdef CFG_ATVRC_ATT |
| #include "bridge_att.h" |
| #ifdef CFG_ATVRC_UNI_IR |
| #include "bridge_ir.h" |
| #endif |
| #ifdef CFG_ATVRC_AUDIO |
| #include "bridge_audio.h" |
| #endif |
| #endif // CFG_ATVRC_ATT |
| #ifdef CFG_ATVRC_CUSTOM |
| #include "atvrc_custom.h" |
| #endif |
| #ifdef CFG_ATVRC_FIND_ME |
| #include "bridge_fms.h" |
| #endif |
| |
| #define MMI_S_TBL_IDX 0 |
| |
| #define ATVV_PEER_TEST_COUNT 1000 |
| |
| ATM_LOG_LOCAL_SETTING("rc_mmi", V); |
| |
| #if PLF_DEBUG |
| static char const * const mmi_s_str[] = { |
| STR(MMI_S_BOOTED), |
| STR(MMI_S_INITING), |
| STR(MMI_S_IDLE), |
| STR(MMI_S_PAIRING), |
| STR(MMI_S_RECONNING), |
| STR(MMI_S_CONNECTED), |
| #ifdef CFG_VOHID |
| STR(MMI_S_HID_READY), |
| STR(MMI_S_HID_STREAMING), |
| #else |
| STR(MMI_S_ATVV_ONLY), |
| STR(MMI_S_HID_ONLY), |
| STR(MMI_S_HID_ATVV), |
| STR(MMI_S_ATVVING), |
| #endif |
| STR(MMI_S_DISCONNING), |
| STR(MMI_S_RF_TEST), |
| STR(MMI_S_PDM_TEST) |
| }; |
| |
| static char const *const mmi_op_str[] = { |
| STR(MMI_OP_INITING), |
| STR(MMI_OP_INIT_DONE), |
| STR(MMI_OP_RECONNING), |
| STR(MMI_OP_PAIRING), |
| STR(MMI_OP_PAIR_FAIL), |
| STR(MMI_OP_RECONN_TOUT), |
| STR(MMI_OP_PAIR_TOUT), |
| STR(MMI_OP_PAIR_SUCCESS), |
| STR(MMI_OP_CONNECTED), |
| STR(MMI_OP_DISCONNED), |
| STR(MMI_OP_HID_READY), |
| #ifndef CFG_VOHID |
| STR(MMI_OP_ATVV_READY), |
| #endif |
| STR(MMI_OP_HID_UNREADY), |
| #ifndef CFG_VOHID |
| STR(MMI_OP_ATVV_UNREADY), |
| #endif |
| STR(MMI_OP_OPEN_MIC), |
| STR(MMI_OP_CLOSE_MIC), |
| STR(MMI_OP_DISCONNING), |
| STR(MMI_OP_ADV_STOPPED), |
| }; |
| |
| STATIC_ASSERT(ARRAY_LEN(mmi_op_str) == MMI_OP_NUM, "Not match"); |
| |
| #endif |
| |
| |
| static uint32_t key_auto_test; |
| static sw_timer_id_t rc_tid_mmi_idle; |
| #ifndef CFG_VOHID |
| static sw_timer_id_t rc_tid_atvv_test; |
| #endif |
| static sw_timer_id_t rc_tid_key_test; |
| static sw_timer_id_t rc_tid_mic_ctl; |
| static void (*app_batt_done_cb)(void); |
| |
| void rc_mmi_transition(mmi_op_t op) |
| { |
| atm_asm_move(MMI_S_TBL_IDX, op); |
| } |
| |
| static void rc_s_changed(ASM_S last_s, ASM_O op, ASM_S next_s) |
| { |
| #if PLF_DEBUG |
| uint8_t nidx = atm_asm_ordinal(next_s); |
| uint8_t oidx = atm_asm_ordinal(op); |
| ATM_LOG(V, ATM_VT_SGR "%s" ATM_VT_SGR " (%s)", ATM_GG_BLUE, |
| mmi_s_str[nidx], ATM_DE_COLOR, mmi_op_str[oidx]); |
| #endif // PLF_DEBUG |
| atm_pm_lock_info(); |
| rc_mmi_vkey_state_change_notify(next_s); |
| } |
| |
| #define RC_MMI_OPEN_MIC_DELAY_CS 1 |
| |
| static void rc_mmi_open_mic(void) |
| { |
| sw_timer_set(rc_tid_mic_ctl, RC_MMI_OPEN_MIC_DELAY_CS); |
| } |
| |
| #ifndef CFG_VOHID |
| static uint16_t atvv_test_cnt_left; |
| |
| #define ATVV_AUTO_TEST_TIMER_CS 700 |
| |
| static void rc_mmi_atvv_test_timer_msg_ind(sw_timer_id_t idx, void const *ctx) |
| { |
| #ifdef CFG_ATVRC_AUDIO |
| if (atvv_test_cnt_left) { |
| #else |
| if ((rc_atvv_state() == BLE_ATVVS_READY) && atvv_test_cnt_left) { |
| #endif |
| rc_gap_local_slave_latency(true); |
| rc_hogp_send_single_key(BT_MIC); |
| rc_hogp_send_single_key(0x00); |
| rc_atvv_start_search(); |
| rc_pdm_device_pwr_on(); |
| rc_mmi_open_mic(); |
| ATM_LOG(N, "audio test left = " ATM_VT_SGR "%d" ATM_VT_SGR, |
| ATM_FG_CYAN, atvv_test_cnt_left, ATM_DE_COLOR); |
| atvv_test_cnt_left--; |
| } |
| |
| if (atvv_test_cnt_left) { |
| sw_timer_set(rc_tid_atvv_test, ATVV_AUTO_TEST_TIMER_CS); |
| } |
| } |
| #endif |
| #ifdef CFG_PDM_LOCAL_TEST |
| static rc_pdm_op_t test_op; |
| #endif |
| |
| static void rc_mmi_idle_timer_msg_ind(sw_timer_id_t idx, void const *ctx) |
| { |
| |
| if (rc_hogp_state() == BLE_HOGPD_READY) { |
| ATM_LOG(N, "idle too long timeout\n"); |
| } else if (rc_hogp_state() == BLE_HOGPD_ENABLED) { |
| ATM_LOG(N, "HID not ready for a long time\n"); |
| } |
| |
| rc_mmi_transition(MMI_OP_DISCONNING); |
| } |
| |
| |
| static void rc_mmi_auto_key_test_timer_msg_ind(sw_timer_id_t idx, void const *ctx) |
| { |
| rc_mmi_idle_timer(MMI_TOUT_START); |
| if (key_auto_test) { |
| ATM_LOG(V, "%" PRIu32 "//%d", (uint32_t)(6000-key_auto_test), 6000); |
| |
| if (key_auto_test & 1){ |
| rc_hogp_send_single_key(BT_UP); |
| rc_hogp_send_single_key(0x00); |
| rc_hogp_send_single_key(BT_DOWN); |
| rc_hogp_send_single_key(0x00); |
| } else { |
| rc_hogp_send_single_key(BT_UP); |
| rc_hogp_send_single_key(0x00); |
| rc_hogp_send_single_key(BT_DOWN); |
| rc_hogp_send_single_key(0x00); |
| } |
| sw_timer_set(rc_tid_key_test, (uint16_t) (50)); |
| } |
| |
| key_auto_test--; |
| } |
| |
| static void rc_mmi_mic_ctl_timer_msg_ind(sw_timer_id_t idx, void const *ctx) |
| { |
| #ifdef CFG_PDM_LOCAL_TEST |
| rc_pdm_start(test_op, false); |
| return; |
| #endif |
| #ifdef CFG_VOHID |
| if (atm_asm_get_current_state(MMI_S_TBL_IDX) == MMI_S_HID_STREAMING) { |
| rc_pdm_start(RC_PDM_NORMAL, false); |
| #else |
| if (atm_asm_get_current_state(MMI_S_TBL_IDX) == MMI_S_ATVVING) { |
| rc_pdm_start(RC_PDM_NORMAL, rc_atvv_is8k()); |
| #endif |
| return; |
| } |
| } |
| |
| #ifdef CFG_USB_DET |
| static void usb_det_intr(uint32_t mask) |
| { |
| atm_gpio_clear_int_status(PIN_USB_DET); |
| if (!atm_gpio_read_gpio(PIN_USB_DET)) { |
| atm_gpio_int_set_rising(PIN_USB_DET); |
| led_off(LED_0); |
| return; |
| } |
| atm_gpio_int_set_falling(PIN_USB_DET); |
| led_on(LED_0); |
| } |
| #endif |
| |
| static void mmi_s_booted_op_initing(void) |
| { |
| rc_gap_init(); |
| rc_pdm_init(); |
| #ifdef CFG_VOHID |
| rc_hidau_init(); |
| #else |
| rc_atvv_init(); |
| #endif |
| #ifdef CFG_RC_IR |
| rc_ir_init(); |
| #endif //CFG_RC_IR |
| |
| #ifndef CFG_VOHID |
| rc_tid_atvv_test = sw_timer_alloc(rc_mmi_atvv_test_timer_msg_ind, NULL); |
| #endif |
| rc_tid_mmi_idle = sw_timer_alloc(rc_mmi_idle_timer_msg_ind, NULL); |
| rc_tid_key_test = sw_timer_alloc(rc_mmi_auto_key_test_timer_msg_ind, NULL); |
| rc_tid_mic_ctl = sw_timer_alloc(rc_mmi_mic_ctl_timer_msg_ind, NULL); |
| |
| #ifdef CFG_USB_DET |
| atm_gpio_setup(PIN_USB_DET); |
| atm_gpio_set_input(PIN_USB_DET); |
| atm_gpio_set_pullup(PIN_USB_DET); |
| interrupt_install_gpio(PIN_USB_DET, IRQ_PRI_UI, usb_det_intr); |
| if (!atm_gpio_read_gpio(PIN_USB_DET)) { |
| atm_gpio_int_set_rising(PIN_USB_DET); |
| } else { |
| atm_gpio_int_set_falling(PIN_USB_DET); |
| led_on(LED_0); |
| } |
| atm_gpio_set_int_enable(PIN_USB_DET); |
| #endif |
| } |
| |
| static void mmi_s_reconnecting_started(void) |
| { |
| #ifndef CFG_ATVRC_MMI |
| led_blink(LED_0, 10, 10, 0xffff); |
| #endif |
| } |
| |
| static void mmi_s_paring_started(void) |
| { |
| led_blink(LED_0, 25, 25, 0xffff); |
| #ifdef CFG_VKEY_BUF |
| rc_mmi_vkey_free_buf(); |
| #else |
| rc_mmi_vkey_clear_saved(); |
| #endif |
| } |
| |
| static void mmi_pairing_stopped_routine(void) |
| { |
| led_off(LED_0); |
| #ifdef CFG_VKEY_BUF |
| rc_mmi_vkey_free_buf(); |
| #else |
| rc_mmi_vkey_clear_saved(); |
| #endif |
| atm_pm_lock_info(); |
| } |
| |
| static void mmi_s_pairing_success_stopped(void) |
| { |
| #ifdef CFG_ATVV_VER_100 |
| rc_atvv_del_config(); |
| #endif |
| mmi_pairing_stopped_routine(); |
| } |
| |
| static void mmi_s_pairing_stopped(void) |
| { |
| mmi_pairing_stopped_routine(); |
| #if (CFG_APP_FEATURE & APP_BATT_AUTO_TIMER_BIT) |
| app_batt_stop(); |
| #else |
| #error "HID_remote only support app_batt with auto timer mode" |
| #endif |
| #ifdef CFG_ATVRC_MMI |
| led_blink(LED_1, ATVRC_LED_ERR_CS, ATVRC_LED_ERR_CS, ATVRC_LED_ERR_BLINK); |
| #endif |
| } |
| |
| static void mmi_s_pairing_disconnected(void) |
| { |
| mmi_s_pairing_stopped(); |
| sw_timer_clear(rc_tid_mmi_idle); |
| } |
| |
| static void mmi_s_pairing_connected(void) |
| { |
| rc_mmi_idle_timer(MMI_TOUT_START); |
| #ifdef CFG_ATVRC_CUSTOM |
| led_blink(LED_0, ATVRC_LED_CFM_CS, ATVRC_LED_CFM_CS, ATVRC_LED_CFM_BLINK); |
| #endif |
| } |
| |
| static void mmi_s_reconnecting_tout(void) |
| { |
| led_off(LED_0); |
| #if (CFG_APP_FEATURE & APP_BATT_AUTO_TIMER_BIT) |
| app_batt_stop(); |
| #endif |
| } |
| |
| static void mmi_s_reconnecting_connected(void) |
| { |
| rc_mmi_idle_timer(MMI_TOUT_START); |
| #ifdef CFG_ATVRC_CUSTOM |
| led_blink(LED_0, ATVRC_LED_CFM_CS, ATVRC_LED_CFM_CS, ATVRC_LED_CFM_BLINK); |
| #else |
| led_off(LED_0); |
| #endif |
| } |
| |
| static void mmi_s_initing_op_done(void) |
| { |
| #ifdef CFG_PDM_LOCAL_TEST |
| rc_mmi_enter_test(MMI_TEST_PDM); |
| #endif |
| #ifdef CFG_RF_TEST |
| rc_mmi_enter_test(MMI_TEST_RF); |
| #endif |
| app_batt_done_cb(); |
| } |
| |
| static void mmi_s_close_mic(void) |
| { |
| rc_pdm_stop(); |
| rc_mmi_idle_timer(MMI_TOUT_START); |
| rc_gap_local_slave_latency(false); |
| #ifdef CFG_ATVRC_MMI |
| if (!rc_atvv_is_htt_model()) { |
| led_off(LED_0); |
| } |
| #endif |
| } |
| |
| static void mmi_s_streaming_open_mic(void) |
| { |
| #ifdef CFG_ATVV_VER_100 |
| // 4.4 |
| // 1. if microphone is open because of a previously |
| // sent MIC_OPEN command, then the Remote should restart an audio |
| // stream and notify Android TV host with AUDIO_START message; |
| ATM_LOG(D, "Mic already opened"); |
| #else |
| ATM_LOG(E, "Mic already opened"); |
| #endif |
| } |
| |
| static void mmi_s_open_mic(void) |
| { |
| rc_gap_local_slave_latency(true); |
| rc_pdm_device_pwr_on(); |
| // wait for device charged. |
| rc_mmi_open_mic(); |
| } |
| |
| static void mmi_s_hid_ready(void) |
| { |
| rc_mmi_idle_timer(MMI_TOUT_START); |
| rc_gap_nego_parameter(); |
| #ifdef CFG_VKEY_BUF |
| rc_mmi_vkey_flush_buf(); |
| #else |
| uint32_t key = rc_mmi_vkey_get_saved(); |
| if (key && (key != BT_MIC)) { |
| rc_hogp_send_single_key(key); |
| rc_hogp_send_single_key(0); |
| rc_mmi_vkey_clear_saved(); |
| } |
| #endif |
| } |
| |
| static void mmi_s_hid_ready_pairing_stopped(void) |
| { |
| mmi_s_pairing_stopped(); |
| mmi_s_hid_ready(); |
| rc_gap_enter_pairing_next_boot(false); |
| } |
| |
| static void mmi_s_disconnecting(void) |
| { |
| rc_pdm_stop(); |
| rc_gap_disconnect(); |
| } |
| |
| static void mmi_s_disconnected(void) |
| { |
| led_off(LED_0); |
| #ifndef CFG_VOHID |
| sw_timer_clear(rc_tid_atvv_test); |
| #endif |
| sw_timer_clear(rc_tid_key_test); |
| sw_timer_clear(rc_tid_mmi_idle); |
| #if (CFG_APP_FEATURE & APP_BATT_AUTO_TIMER_BIT) |
| app_batt_stop(); |
| #endif |
| } |
| |
| static void mmi_s_prf_disconnected(void) |
| { |
| mmi_s_disconnected(); |
| rc_pdm_stop(); |
| key_auto_test = 0; |
| } |
| |
| static void mmi_s_unexp_disconnected(void) |
| { |
| ATM_LOG(E, "Unexpected disconnection."); |
| #ifdef CFG_VOHID |
| rc_hidau_stop_search(); |
| #else |
| rc_atvv_stop_search(); |
| #endif |
| mmi_s_prf_disconnected(); |
| } |
| |
| static state_entry const mmi_s_tbl[] = { |
| {MMI_S_BOOTED, MMI_OP_INITING, MMI_S_INITING, mmi_s_booted_op_initing}, |
| {MMI_S_IDLE, MMI_OP_RECONNING, MMI_S_RECONNING, mmi_s_reconnecting_started}, |
| #ifndef CFG_VOHID |
| {MMI_S_IDLE, MMI_OP_ATVV_UNREADY, MMI_S_IDLE, NULL}, |
| #endif |
| {MMI_S_IDLE, MMI_OP_PAIRING, MMI_S_PAIRING, mmi_s_paring_started}, |
| {MMI_S_IDLE, MMI_OP_DISCONNING, MMI_S_IDLE, NULL}, |
| {MMI_S_IDLE, MMI_OP_DISCONNED, MMI_S_IDLE, NULL}, |
| {MMI_S_IDLE, MMI_OP_PAIR_FAIL, MMI_S_IDLE, NULL}, |
| {MMI_S_IDLE, MMI_OP_CLOSE_MIC, MMI_S_IDLE, mmi_s_close_mic}, |
| {MMI_S_INITING, MMI_OP_INIT_DONE, MMI_S_IDLE, mmi_s_initing_op_done}, |
| {MMI_S_INITING, MMI_OP_RECONNING, MMI_S_RECONNING, |
| mmi_s_reconnecting_started}, |
| {MMI_S_INITING, MMI_OP_PAIRING, MMI_S_PAIRING, mmi_s_paring_started}, |
| {MMI_S_RECONNING, MMI_OP_CONNECTED, MMI_S_CONNECTED, |
| mmi_s_reconnecting_connected}, |
| {MMI_S_RECONNING, MMI_OP_RECONN_TOUT, MMI_S_IDLE, mmi_s_reconnecting_tout}, |
| {MMI_S_RECONNING, MMI_OP_ADV_STOPPED, MMI_S_IDLE, NULL}, |
| {MMI_S_PAIRING, MMI_OP_CONNECTED, MMI_S_PAIRING, mmi_s_pairing_connected}, |
| #ifdef CFG_ATVRC_WAKEUP |
| {MMI_S_IDLE, MMI_OP_RECONN_TOUT, MMI_S_IDLE, NULL}, |
| {MMI_S_RECONNING, MMI_OP_DISCONNING, MMI_S_IDLE, NULL}, |
| {MMI_S_PAIRING, MMI_OP_DISCONNING, MMI_S_PAIRING, NULL}, |
| #else |
| {MMI_S_PAIRING, MMI_OP_DISCONNING, MMI_S_DISCONNING, mmi_s_disconnecting}, |
| #endif |
| {MMI_S_PAIRING, MMI_OP_DISCONNED, MMI_S_IDLE, mmi_s_pairing_disconnected}, |
| {MMI_S_PAIRING, MMI_OP_PAIR_FAIL, MMI_S_CONNECTED, mmi_s_pairing_stopped}, |
| {MMI_S_PAIRING, MMI_OP_PAIR_TOUT, MMI_S_IDLE, mmi_s_pairing_stopped}, |
| {MMI_S_PAIRING, MMI_OP_PAIR_SUCCESS, MMI_S_CONNECTED, |
| mmi_s_pairing_success_stopped}, |
| {MMI_S_PAIRING, MMI_OP_ADV_STOPPED, MMI_S_IDLE, mmi_s_pairing_stopped}, |
| #ifdef CFG_VOHID |
| {MMI_S_PAIRING, MMI_OP_HID_READY, MMI_S_HID_READY, |
| mmi_s_hid_ready_pairing_stopped}, |
| {MMI_S_CONNECTED, MMI_OP_HID_READY, MMI_S_HID_READY, mmi_s_hid_ready}, |
| #else |
| {MMI_S_PAIRING, MMI_OP_HID_READY, MMI_S_HID_ONLY, |
| mmi_s_hid_ready_pairing_stopped}, |
| #ifdef CFG_ATVRC_AUDIO |
| {MMI_S_PAIRING, MMI_OP_ATVV_UNREADY, MMI_S_PAIRING, NULL}, |
| {MMI_S_PAIRING, MMI_OP_ATVV_READY, MMI_S_ATVV_ONLY, NULL}, |
| {MMI_S_ATVV_ONLY, MMI_OP_PAIR_SUCCESS, MMI_S_ATVV_ONLY, NULL}, |
| {MMI_S_ATVV_ONLY, MMI_OP_PAIR_FAIL, MMI_S_ATVV_ONLY, NULL}, |
| #endif |
| {MMI_S_CONNECTED, MMI_OP_ATVV_READY, MMI_S_ATVV_ONLY, NULL}, |
| {MMI_S_CONNECTED, MMI_OP_HID_READY, MMI_S_HID_ONLY, mmi_s_hid_ready}, |
| #endif |
| {MMI_S_CONNECTED, MMI_OP_DISCONNING, MMI_S_DISCONNING, mmi_s_disconnecting}, |
| {MMI_S_CONNECTED, MMI_OP_DISCONNED, MMI_S_IDLE, mmi_s_disconnected}, |
| #ifndef CFG_VOHID |
| {MMI_S_CONNECTED, MMI_OP_ATVV_UNREADY, MMI_S_CONNECTED, NULL}, |
| #endif |
| {MMI_S_CONNECTED, MMI_OP_PAIR_SUCCESS, MMI_S_CONNECTED, NULL}, |
| {MMI_S_CONNECTED, MMI_OP_PAIR_FAIL, MMI_S_CONNECTED, NULL}, |
| #ifdef CFG_VOHID |
| {MMI_S_HID_READY, MMI_OP_OPEN_MIC, MMI_S_HID_STREAMING, mmi_s_open_mic}, |
| {MMI_S_HID_READY, MMI_OP_DISCONNED, MMI_S_IDLE, mmi_s_prf_disconnected}, |
| {MMI_S_HID_READY, MMI_OP_DISCONNING, MMI_S_DISCONNING, mmi_s_disconnecting}, |
| {MMI_S_HID_STREAMING, MMI_OP_OPEN_MIC, MMI_S_HID_STREAMING, |
| mmi_s_streaming_open_mic}, |
| {MMI_S_HID_STREAMING, MMI_OP_CLOSE_MIC, MMI_S_HID_READY, mmi_s_close_mic}, |
| {MMI_S_HID_STREAMING, MMI_OP_DISCONNED, MMI_S_IDLE, |
| mmi_s_unexp_disconnected}, |
| #else |
| {MMI_S_HID_ONLY, MMI_OP_ATVV_READY, MMI_S_HID_ATVV, mmi_s_hid_ready}, |
| {MMI_S_HID_ONLY, MMI_OP_ATVV_UNREADY, MMI_S_HID_ONLY, NULL}, |
| {MMI_S_ATVV_ONLY, MMI_OP_ATVV_UNREADY, MMI_S_CONNECTED, NULL}, |
| {MMI_S_ATVV_ONLY, MMI_OP_HID_READY, MMI_S_HID_ATVV, mmi_s_hid_ready}, |
| {MMI_S_ATVV_ONLY, MMI_OP_ATVV_READY, MMI_S_ATVV_ONLY, NULL}, |
| {MMI_S_ATVV_ONLY, MMI_OP_DISCONNED, MMI_S_IDLE, mmi_s_prf_disconnected}, |
| {MMI_S_HID_ATVV, MMI_OP_ATVV_READY, MMI_S_HID_ATVV, NULL}, |
| {MMI_S_HID_ATVV, MMI_OP_ATVV_UNREADY, MMI_S_HID_ONLY, NULL}, |
| {MMI_S_HID_ATVV, MMI_OP_OPEN_MIC, MMI_S_ATVVING, mmi_s_open_mic}, |
| {MMI_S_HID_ATVV, MMI_OP_DISCONNED, MMI_S_IDLE, mmi_s_prf_disconnected}, |
| {MMI_S_ATVV_ONLY, MMI_OP_DISCONNING, MMI_S_DISCONNING, mmi_s_disconnecting}, |
| {MMI_S_HID_ATVV, MMI_OP_DISCONNING, MMI_S_DISCONNING, mmi_s_disconnecting}, |
| {MMI_S_HID_ONLY, MMI_OP_DISCONNING, MMI_S_DISCONNING, mmi_s_disconnecting}, |
| {MMI_S_HID_ONLY, MMI_OP_DISCONNED, MMI_S_IDLE, mmi_s_prf_disconnected}, |
| {MMI_S_ATVVING, MMI_OP_CLOSE_MIC, MMI_S_HID_ATVV, mmi_s_close_mic}, |
| {MMI_S_ATVVING, MMI_OP_OPEN_MIC, MMI_S_ATVVING, mmi_s_streaming_open_mic}, |
| {MMI_S_ATVVING, MMI_OP_DISCONNED, MMI_S_IDLE, mmi_s_unexp_disconnected}, |
| {MMI_S_HID_ATVV, MMI_OP_CLOSE_MIC, MMI_S_HID_ATVV, NULL}, |
| #endif |
| {MMI_S_DISCONNING, MMI_OP_DISCONNED, MMI_S_IDLE, mmi_s_disconnected}, |
| {MMI_S_RF_TEST, MMI_OP_DISCONNED, MMI_S_RF_TEST, NULL}, |
| }; |
| |
| static void rc_batt_app_start(void (*done)(void)) |
| { |
| rc_mmi_transition(MMI_OP_INITING); |
| |
| app_batt_done_cb = done; |
| } |
| |
| static void rc_batt_app_stop(void (*done)(void)) |
| { |
| if (atm_asm_get_current_state(MMI_S_TBL_IDX) != MMI_S_BOOTED) { |
| led_off(LED_0); |
| rc_gap_stop(); |
| } |
| done(); |
| } |
| |
| static rep_vec_err_t rc_mmi_plf_reset(void) |
| { |
| led_off(LED_0); |
| |
| return (RV_NEXT); |
| } |
| |
| void rc_mmi_init(void) |
| { |
| RV_PLF_RESET_ADD(rc_mmi_plf_reset); |
| #ifdef CFG_ATVRC_CUSTOM |
| atvrc_custom_init(); |
| rc_mmi_vkey_update_ui(atvrc_custom_get_ui_layout()); |
| #endif |
| #if defined(CFG_ATVRC_UNI_IR) || defined(CFG_ATVRC_AUDIO) |
| bridge_att_init(); |
| #endif |
| #ifdef CFG_ATVRC_UNI_IR |
| bridge_ir_init(); |
| #endif |
| #ifdef CFG_ATVRC_AUDIO |
| bridge_audio_init(); |
| #endif |
| #ifdef CFG_ATVRC_FIND_ME |
| bridge_fms_init(); |
| #endif |
| atm_asm_init_table(MMI_S_TBL_IDX, mmi_s_tbl, ARRAY_LEN(mmi_s_tbl)); |
| atm_asm_reg_state_change_cb(MMI_S_TBL_IDX, rc_s_changed); |
| atm_asm_set_current_state(MMI_S_TBL_IDX, MMI_S_BOOTED); |
| static app_batt_cbs_t const cbs = { |
| .app_start = rc_batt_app_start, |
| .app_stop = rc_batt_app_stop, |
| .level_update = app_bass_send_battery_lvl, |
| }; |
| app_batt_start(&cbs); |
| } |
| |
| void rc_mmi_idle_timer(mmi_tout_t op) |
| { |
| uint8_t state = atm_asm_get_current_state(MMI_S_TBL_IDX); |
| switch (op) { |
| case MMI_TOUT_START: { |
| #ifdef CFG_VOHID |
| if (state == MMI_S_HID_READY) { |
| #else |
| if (state == MMI_S_HID_ONLY || state == MMI_S_HID_ATVV) { |
| #endif |
| if (RC_CONN_READY_TOUT_CS) { |
| sw_timer_set(rc_tid_mmi_idle, RC_CONN_READY_TOUT_CS); |
| } else { |
| sw_timer_clear(rc_tid_mmi_idle); |
| } |
| } else { |
| if (RC_CONN_NOT_READY_TOUT_CS) { |
| sw_timer_set(rc_tid_mmi_idle, RC_CONN_NOT_READY_TOUT_CS); |
| } else { |
| sw_timer_clear(rc_tid_mmi_idle); |
| } |
| } |
| } break; |
| case MMI_TOUT_STOP: { |
| sw_timer_clear(rc_tid_mmi_idle); |
| } break; |
| case MMI_TOUT_FORCE: { |
| sw_timer_set(rc_tid_mmi_idle, 100); |
| } break; |
| default: |
| break; |
| } |
| } |
| |
| #ifdef CFG_PDM_LOCAL_TEST |
| #define MAX_TEST_TIME_CS 5000 |
| #define MIN_TEST_TIME_CS 500 |
| #ifndef TEST_COUNT |
| #define TEST_COUNT 20 |
| #endif |
| |
| static char const * const test_type_str [] = { |
| "", "", "Frequency test", "Overflow test", "No buffer test" |
| }; |
| static sw_timer_id_t test_tid; |
| static uint16_t test_count; |
| static void start_test(void) |
| { |
| test_op = (rand() % (RC_PDM_LOCAL_TEST_MAX - 2)) + 2; |
| uint32_t test_time = (rand() % (MAX_TEST_TIME_CS - MIN_TEST_TIME_CS)) + |
| MIN_TEST_TIME_CS; |
| sw_timer_set(test_tid, test_time); |
| sw_timer_clear(rc_tid_mmi_idle); |
| rc_pdm_device_pwr_on(); |
| #ifdef CFG_VOHID |
| rc_hidau_test_start(); |
| #else |
| rc_atvv_test_start(); |
| #endif |
| rc_mmi_open_mic(); |
| ATM_LOG(N, "PDM testing[%d] (%" PRIu32 " s): " ATM_VT_SGR "%s" ATM_VT_SGR, |
| test_count, CO_DIVIDE_ROUND(test_time, 100), ATM_FG_CYAN, |
| test_type_str[test_op], ATM_DE_COLOR); |
| |
| } |
| |
| static void stop_start(sw_timer_id_t tid, void const *ctx) |
| { |
| atm_asm_set_current_state(MMI_S_TBL_IDX, MMI_S_PDM_TEST); |
| static bool not_first_time; |
| if (not_first_time) { |
| rc_pdm_stop(); |
| } else { |
| not_first_time = true; |
| } |
| |
| if (++test_count == TEST_COUNT) { |
| ATM_LOG(N, "pdm_local_test passed !"); |
| #ifdef AUTO_TEST |
| UartEndSimulation(); |
| #endif |
| return; |
| } |
| start_test(); |
| } |
| #endif // CFG_PDM_LOCAL_TEST |
| |
| void rc_mmi_enter_test(mmi_test_t op) |
| { |
| switch(op) { |
| case MMI_TEST_KEY: { |
| ATM_LOG(N, "key current test start!! 6000 times"); |
| key_auto_test = 6000; |
| sw_timer_set(rc_tid_key_test, (uint16_t)(50)); |
| rc_mmi_idle_timer(MMI_TOUT_STOP); |
| } break; |
| case MMI_TEST_RF: { |
| ATM_LOG(N, "rftest"); |
| atm_asm_set_current_state(MMI_S_TBL_IDX, MMI_S_RF_TEST); |
| led_blink(LED_0, 10, 10, 0xffff); |
| rc_gap_enter_rf_test(); |
| } break; |
| #ifndef CFG_VOHID |
| case MMI_TEST_ATVV: { |
| rc_mmi_idle_timer(MMI_TOUT_STOP); |
| atvv_test_cnt_left = ATVV_PEER_TEST_COUNT; |
| sw_timer_set(rc_tid_atvv_test, (uint16_t)(50)); |
| } break; |
| #endif |
| #ifdef CFG_PDM_LOCAL_TEST |
| case MMI_TEST_PDM: { |
| test_tid = sw_timer_alloc(stop_start, NULL); |
| sw_timer_set(test_tid, 10); |
| } break; |
| #endif // CFG_PDM_LOCAL_TEST |
| default: |
| break; |
| } |
| } |