blob: 6f913c0b4c7547ecfed7df8d1a4a9cc2515bbef5 [file] [log] [blame]
/*
*******************************************************************************
*
* @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;
}
}