2025-02-18 15:40:42 +08:00

378 lines
9.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*********************************************************************************************
* Filename : app_gamebox.c
* Description :
* Author :
* Email :
* Last modifiled : 2020-03-24 09:52:50
* Copyright:(c)JIELI 2011-2020 @ , All Rights Reserved.
*********************************************************************************************/
#include "system/app_core.h"
#include "system/includes.h"
#include "server/server_core.h"
#include "app_config.h"
#include "app_action.h"
#include "os/os_api.h"
#include "btcontroller_config.h"
#include "btctrler/btctrler_task.h"
#include "config/config_transport.h"
#include "btstack/avctp_user.h"
#include "btstack/btstack_task.h"
#include "bt_common.h"
#include "le_common.h"
#include "rcsp_bluetooth.h"
#include "rcsp_user_update.h"
#include "app_charge.h"
#include "app_power_manage.h"
#include "app_config.h"
#include "usb_hid_keys.h"
#include "gamebox.h"
#include "app_comm_bt.h"
#if(CONFIG_APP_GAMEBOX)
#if TCFG_USER_EDR_ENABLE
//配置需要一致
#error "need disable TCFG_USER_EDR_ENABLE,no support!!!!!!"
#endif
#define LOG_TAG_CONST GAMEBOX
#define LOG_TAG "[GAMBOX]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
static u16 g_auto_shutdown_timer = 0;
static u8 is_gamebox_active = 0;//1-临界点,系统不允许进入低功耗0-系统可以进入低功耗
extern void gamebox_init();
extern int app_send_user_data(u16 handle, u8 *data, u16 len, u8 handle_type);
extern int ble_hid_data_send(u8 report_id, u8 *data, u16 len);
//----------------------------------
static const ble_init_cfg_t gamebox_ble_config = {
.same_address = 0,
.appearance = BLE_APPEARANCE_HID_GAMEPAD,
.report_map = hid_report_desc,
.report_map_size = sizeof(hid_report_desc),
};
//----------------------------------
#define BUTTONS_IDX 0
#define WHEEL_IDX (BUTTONS_IDX + 1)
#define SENSOR_XLSB_IDX 0
#define SENSOR_YLSB_XMSB_IDX (SENSOR_XLSB_IDX + 1)
#define SENSOR_YMSB_IDX (SENSOR_YLSB_XMSB_IDX +1)
extern int ble_hid_timer_handle;
static u8 button_send_flag = 0;
static u8 wheel_send_flag = 0;
static u8 sensor_send_flag = 0;
int ble_hid_is_connected(void);
extern int ble_hid_transfer_channel_send(u8 *packet, u16 size);
void send2phone(u32 type, const void *_p)
{
if (type == 0x32 /*USB_CLASS_HID_MOUSE*/) {
const struct mouse_data_t *p = _p;
//usb isr 和ble(timer) 发送放在同一个中断优先级,所以不加互斥
mouse_data.btn = p->btn;
mouse_data.wheel += p->wheel;
mouse_data.x += p->x;
mouse_data.y += p->y;
mouse_data_send = 1;
}
if (!ble_hid_is_connected()) {
return ;
}
if (type == 0x37) {
ble_hid_transfer_channel_send(_p, 8);
} else if (type == 0x33) {
struct mouse_data_t pp ;
struct mouse_data_t *p = _p;
pp.btn = p->btn;
p = &pp;
p->x = -1;
p->y = -1;
p->wheel = -1;
p->ac_pan = -1;
p->btn &= ~BIT(2);
if (p->btn) {
ble_hid_transfer_channel_send(p, 8);
}
}
}
void gamebox_auto_shutdown_disable(void)
{
log_info("----%s", __FUNCTION__);
if (g_auto_shutdown_timer) {
sys_timeout_del(g_auto_shutdown_timer);
}
}
extern void p33_soft_reset(void);
static void gamebox_power_set_soft_reset(void)
{
p33_soft_reset();
while (1);
}
static void gamebox_ble_mouse_timer_handler(void)
{
if (!ble_hid_is_connected()) {
if (get_phone_connect_status() == BT_MODE) {
set_phone_connect_status(0);
}
return;
}
set_phone_connect_status(BT_MODE);
if (mouse_data_send == 1) {
int r = ble_hid_data_send(2, &mouse_data, sizeof(mouse_data));
memset(&mouse_data, 0, sizeof(mouse_data)) ;
mouse_data_send = 0;
}
struct touch_screen_t t;
memset(&t, 0, sizeof(t));
if (point_list_pop(&t)) {
ble_hid_data_send(1, &t, sizeof(t));
}
}
void gamebox_power_event_to_user(u8 event)
{
struct sys_event e;
e.type = SYS_DEVICE_EVENT;
e.arg = (void *)DEVICE_EVENT_FROM_POWER;
e.u.dev.event = event;
e.u.dev.value = 0;
sys_event_notify(&e);
}
static void gamebox_set_soft_poweroff(void)
{
log_info("gamebox_set_soft_poweroff\n");
is_gamebox_active = 1;
//必须先主动断开蓝牙链路,否则要等链路超时断开
#if TCFG_USER_BLE_ENABLE
ble_module_enable(0);
#endif
sys_timeout_add(NULL, power_set_soft_poweroff, WAIT_DISCONN_TIME_MS);
}
extern void bt_pll_para(u32 osc, u32 sys, u8 low_power, u8 xosc);
static void gamebox_app_start()
{
gamebox_init();
log_info("=======================================");
log_info("------------- gamebox -----------------");
log_info("=======================================");
log_info("app_file: %s", __FILE__);
clk_set("sys", BT_NORMAL_HZ);
//有蓝牙
#if (TCFG_USER_EDR_ENABLE || TCFG_USER_BLE_ENABLE)
u32 sys_clk = clk_get("sys");
bt_pll_para(TCFG_CLOCK_OSC_HZ, sys_clk, 0, 0);
#if TCFG_USER_BLE_ENABLE
btstack_ble_start_before_init(&gamebox_ble_config, 0);
btstack_init();
#endif
#else
//no bt,to for test
log_info("not bt!!!!!!");
#endif
#if (TCFG_HID_AUTO_SHUTDOWN_TIME)
//无操作定时软关机
g_auto_shutdown_timer = sys_timeout_add(POWER_EVENT_POWER_SOFTOFF, gamebox_power_event_to_user, TCFG_HID_AUTO_SHUTDOWN_TIME * 1000);
#endif
}
static int gamebox_state_machine(struct application *app, enum app_state state, struct intent *it)
{
switch (state) {
case APP_STA_CREATE:
break;
case APP_STA_START:
if (!it) {
break;
}
switch (it->action) {
case ACTION_GAMEBOX:
gamebox_app_start();
break;
}
break;
case APP_STA_PAUSE:
break;
case APP_STA_RESUME:
break;
case APP_STA_STOP:
break;
case APP_STA_DESTROY:
log_info("APP_STA_DESTROY\n");
break;
}
return 0;
}
static int gamebox_bt_hci_event_handler(struct bt_event *bt)
{
//对应原来的蓝牙连接上断开处理函数 ,bt->value=reason
log_info("----%s reason %x %x", __FUNCTION__, bt->event, bt->value);
#if TCFG_USER_BLE_ENABLE
bt_comm_ble_hci_event_handler(bt);
#endif
return 0;
}
extern void le_hogp_set_PNP_info(const u8 *info);
static const u8 gambox_PnP_ID[] = {0x02, 0x17, 0x27, 0x40, 0x00, 0x23, 0x00};
static int gamebox_bt_connction_status_event_handler(struct bt_event *bt)
{
log_info("----%s %d", __FUNCTION__, bt->event);
#if TCFG_USER_BLE_ENABLE
bt_comm_ble_status_event_handler(bt);
switch (bt->event) {
case BT_STATUS_INIT_OK:
/*
* 蓝牙初始化完成
*/
log_info("BT_STATUS_INIT_OK\n");
log_info("set gamebox pnp\n");
le_hogp_set_PNP_info(gambox_PnP_ID);
ble_module_enable(1);
ble_hid_timer_handle = sys_s_hi_timer_add((void *)0, gamebox_ble_mouse_timer_handler, 10);
break;
default:
break;
}
#endif
return 0;
}
static int gamebox_bt_common_event_handler(struct bt_event *bt)
{
log_info("----%s reason %x %x", __FUNCTION__, bt->event, bt->value);
switch (bt->event) {
case COMMON_EVENT_EDR_REMOTE_TYPE:
log_info(" COMMON_EVENT_EDR_REMOTE_TYPE,%d \n", bt->value);
break;
case COMMON_EVENT_BLE_REMOTE_TYPE:
log_info(" COMMON_EVENT_BLE_REMOTE_TYPE,%d \n", bt->value);
break;
case COMMON_EVENT_SHUTDOWN_DISABLE:
gamebox_auto_shutdown_disable();
break;
default:
break;
}
return 0;
}
static int gamebox_event_handler(struct application *app, struct sys_event *event)
{
#if (TCFG_HID_AUTO_SHUTDOWN_TIME)
//重置无操作定时计数
if (event->type != SYS_DEVICE_EVENT || DEVICE_EVENT_FROM_POWER != event->arg) { //过滤电源消息
sys_timer_modify(g_auto_shutdown_timer, TCFG_HID_AUTO_SHUTDOWN_TIME * 1000);
}
#endif
/* log_info("event: %s", event->arg); */
switch (event->type) {
case SYS_KEY_EVENT:
log_info("Sys Key : %s", event->arg);
/* app_key_event_handler(event); */
return 0;
case SYS_BT_EVENT:
if ((u32)event->arg == SYS_BT_EVENT_TYPE_CON_STATUS) {
gamebox_bt_connction_status_event_handler(&event->u.bt);
} else if ((u32)event->arg == SYS_BT_EVENT_TYPE_HCI_STATUS) {
gamebox_bt_hci_event_handler(&event->u.bt);
} else if ((u32)event->arg == SYS_BT_EVENT_FORM_COMMON) {
return gamebox_bt_common_event_handler(&event->u.dev);
}
return 0;
case SYS_DEVICE_EVENT:
if ((u32)event->arg == DEVICE_EVENT_FROM_POWER) {
return app_power_event_handler(&event->u.dev, gamebox_power_set_soft_reset);
}
#if TCFG_CHARGE_ENABLE
else if ((u32)event->arg == DEVICE_EVENT_FROM_CHARGE) {
app_charge_event_handler(&event->u.dev);
}
#endif
return 0;
default:
return FALSE;
}
return FALSE;
}
//-----------------------
//system check go sleep is ok
static u8 gamebox_idle_query(void)
{
return !is_gamebox_active;
}
REGISTER_LP_TARGET(app_gamebox_lp_target) = {
.name = "app_gamebox_deal",
.is_idle = gamebox_idle_query,
};
static const struct application_operation app_gamebox_ops = {
.state_machine = gamebox_state_machine,
.event_handler = gamebox_event_handler,
};
/*
* 注册AT Module模式
*/
REGISTER_APPLICATION(app_gamebox) = {
.name = "gamebox",
.action = ACTION_GAMEBOX,
.ops = &app_gamebox_ops,
.state = APP_STA_DESTROY,
};
#endif