KT24-1110_65E-HA-651B/apps/common/usb/device/task_pc.c
2024-11-10 18:44:17 +08:00

422 lines
10 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.

/**
* @file task_pc.c
* @brief 从机模式
* @author chenrixin@zh-jieli.com
* @version 1.0.0
* @date 2020-02-29
*/
#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 "device/sdmmc.h"
#include "app_sound_box_tool.h"
#include "app_charge.h"
#include "asm/charge.h"
#if TCFG_USB_SLAVE_ENABLE
#ifndef USB_PC_NO_APP_MODE
#include "app_task.h"
#endif
#include "usb/usb_config.h"
#include "usb/device/usb_stack.h"
#if TCFG_USB_SLAVE_HID_ENABLE
#include "usb/device/hid.h"
#endif
#if TCFG_USB_SLAVE_MSD_ENABLE
#include "usb/device/msd.h"
#endif
#if TCFG_USB_SLAVE_CDC_ENABLE
#include "usb/device/cdc.h"
#endif
#if (TCFG_USB_DM_MULTIPLEX_WITH_SD_DAT0)
#include "dev_multiplex_api.h"
#endif
#if TCFG_USB_APPLE_DOCK_EN
#include "apple_dock/iAP.h"
#endif
#define LOG_TAG_CONST USB
#define LOG_TAG "[USB_TASK]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
#define USB_TASK_NAME "usb_msd"
#define USBSTACK_EVENT 0x80
#define USBSTACK_MSD_RUN 0x81
#define USBSTACK_MSD_RELASE 0x82
#define USBSTACK_HID 0x83
#define USBSTACK_MSD_RESET 0x84
extern int usb_audio_demo_init(void);
extern void usb_audio_demo_exit(void);
static usb_dev usbfd = 0;//SEC(.usb_g_bss);
static OS_MUTEX msd_mutex ;//SEC(.usb_g_bss);
static u8 msd_in_task;
static u8 msd_run_reset;
static void usb_task(void *p)
{
int ret = 0;
int msg[16];
while (1) {
ret = os_task_pend("taskq", msg, ARRAY_SIZE(msg));
if (ret != OS_TASKQ) {
continue;
}
if (msg[0] != Q_MSG) {
continue;
}
switch (msg[1]) {
#if TCFG_USB_SLAVE_MSD_ENABLE
case USBSTACK_MSD_RUN:
os_mutex_pend(&msd_mutex, 0);
msd_in_task = 1;
#if TCFG_USB_APPLE_DOCK_EN
apple_mfi_link((void *)msg[2]);
#else
USB_MassStorage((void *)msg[2]);
#endif
if (msd_run_reset) {
msd_reset((struct usb_device_t *)msg[2], 0);
msd_run_reset = 0;
}
msd_in_task = 0;
os_mutex_post(&msd_mutex);
break;
case USBSTACK_MSD_RELASE:
os_sem_post((OS_SEM *)msg[2]);
while (1) {
os_time_dly(10000);
}
break;
// case USBSTACK_MSD_RESET:
// os_mutex_pend(&msd_mutex, 0);
// msd_reset((struct usb_device_t *)msg[2], (u32)msg[3]);
// os_mutex_post(&msd_mutex);
// break;
#endif
default:
break;
}
}
}
static void usb_msd_wakeup(struct usb_device_t *usb_device)
{
os_taskq_post_msg(USB_TASK_NAME, 2, USBSTACK_MSD_RUN, usb_device);
}
static void usb_msd_reset_wakeup(struct usb_device_t *usb_device, u32 itf_num)
{
/* os_taskq_post_msg(USB_TASK_NAME, 3, USBSTACK_MSD_RESET, usb_device, itf_num); */
if (msd_in_task) {
msd_run_reset = 1;
} else {
#if TCFG_USB_SLAVE_MSD_ENABLE
msd_reset(usb_device, 0);
#endif
}
}
static void usb_msd_init()
{
r_printf("%s()", __func__);
int err;
os_mutex_create(&msd_mutex);
err = task_create(usb_task, NULL, USB_TASK_NAME);
if (err != OS_NO_ERR) {
r_printf("usb_msd task creat fail %x\n", err);
}
}
static void usb_msd_free()
{
r_printf("%s()", __func__);
os_mutex_del(&msd_mutex, 0);
int err;
OS_SEM sem;
os_sem_create(&sem, 0);
os_taskq_post_msg(USB_TASK_NAME, 2, USBSTACK_MSD_RELASE, (int)&sem);
os_sem_pend(&sem, 0);
err = task_kill(USB_TASK_NAME);
if (!err) {
r_printf("usb_msd_uninit succ!!\n");
} else {
r_printf("usb_msd_uninit fail!!\n");
}
}
#if TCFG_USB_SLAVE_CDC_ENABLE
static void usb_cdc_wakeup(struct usb_device_t *usb_device)
{
//回调函数在中断里,正式使用不要在这里加太多东西阻塞中断,
//或者先post到任务由任务调用cdc_read_data()读取再执行后续工作
const usb_dev usb_id = usb_device2id(usb_device);
u8 buf[64] = {0};
static u8 buf_rx[256] = {0};
static u8 rx_len_total = 0;
u32 rlen;
log_debug("cdc rx hook");
rlen = cdc_read_data(usb_id, buf, 64);
/* put_buf(buf, rlen);//固件三部测试使用 */
/* cdc_write_data(usb_id, buf, rlen);//固件三部测试使用 */
if ((buf[0] == 0x5A) && (buf[1] == 0xAA) && (buf[2] == 0xA5)) {
memset(buf_rx, 0, 256);
memcpy(buf_rx, buf, rlen);
/* log_info("need len = %d\n", buf_rx[5] + 6); */
/* log_info("rx len = %d\n", rlen); */
if ((buf_rx[5] + 6) == rlen) {
rx_len_total = 0;
#if (TCFG_SOUNDBOX_TOOL_ENABLE || TCFG_EFFECT_TOOL_ENABLE)
#if (TCFG_COMM_TYPE == TCFG_USB_COMM)
/* put_buf(buf_rx, rlen); */
online_cfg_tool_data_deal(buf_rx, rlen);
#else
put_buf(buf, rlen);
cdc_write_data(usb_id, buf, rlen);
#endif
#endif
} else {
rx_len_total += rlen;
}
} else {
if ((rx_len_total + rlen) > 256) {
memset(buf_rx, 0, 256);
rx_len_total = 0;
return;
}
memcpy(buf_rx + rx_len_total, buf, rlen);
/* log_info("need len = %d\n", buf_rx[5] + 6); */
/* log_info("rx len = %d\n", rx_len_total + rlen); */
if ((buf_rx[5] + 6) == (rx_len_total + rlen)) {
#if (TCFG_SOUNDBOX_TOOL_ENABLE || TCFG_EFFECT_TOOL_ENABLE)
#if (TCFG_COMM_TYPE == TCFG_USB_COMM)
/* put_buf(buf_rx, rx_len_total + rlen); */
online_cfg_tool_data_deal(buf_rx, rx_len_total + rlen);
#else
put_buf(buf, rlen);
cdc_write_data(usb_id, buf, rlen);
#endif
#endif
rx_len_total = 0;
} else {
rx_len_total += rlen;
}
}
}
#endif
void usb_start()
{
#if TCFG_USB_SLAVE_AUDIO_ENABLE
usb_audio_demo_init();
#endif
#ifdef USB_DEVICE_CLASS_CONFIG
g_printf("USB_DEVICE_CLASS_CONFIG:%x", USB_DEVICE_CLASS_CONFIG);
#if TCFG_USB_CDC_BACKGROUND_RUN
usb_device_mode(usbfd, USB_DEVICE_CLASS_CONFIG | CDC_CLASS);
#else
usb_device_mode(usbfd, USB_DEVICE_CLASS_CONFIG);
#endif
#endif
#if TCFG_USB_SLAVE_MSD_ENABLE
//没有复用时候判断 sd开关
//复用时候判断是否参与复用
#if (!TCFG_USB_DM_MULTIPLEX_WITH_SD_DAT0 && TCFG_SD0_ENABLE)\
||(TCFG_SD0_ENABLE && TCFG_USB_DM_MULTIPLEX_WITH_SD_DAT0 && TCFG_DM_MULTIPLEX_WITH_SD_PORT != 0)
msd_register_disk("sd0", NULL);
#endif
#if (!TCFG_USB_DM_MULTIPLEX_WITH_SD_DAT0 && TCFG_SD1_ENABLE)\
||(TCFG_SD1_ENABLE && TCFG_USB_DM_MULTIPLEX_WITH_SD_DAT0 && TCFG_DM_MULTIPLEX_WITH_SD_PORT != 1)
msd_register_disk("sd1", NULL);
#endif
#if TCFG_NOR_FAT
msd_register_disk("fat_nor", NULL);
#endif
#if TCFG_VIR_UDISK_ENABLE
msd_register_disk("vir_udisk0", NULL);
#endif
msd_set_wakeup_handle(usb_msd_wakeup);
msd_set_reset_wakeup_handle(usb_msd_reset_wakeup);
usb_msd_init();
#endif
#if TCFG_USB_SLAVE_CDC_ENABLE
cdc_set_wakeup_handler(usb_cdc_wakeup);
#endif
}
static void usb_remove_disk()
{
#if TCFG_USB_SLAVE_MSD_ENABLE
os_mutex_pend(&msd_mutex, 0);
msd_unregister_all();
os_mutex_post(&msd_mutex);
#endif
}
void usb_pause()
{
log_info("usb pause");
usb_sie_disable(usbfd);
#if TCFG_USB_SLAVE_MSD_ENABLE
if (msd_set_wakeup_handle(NULL)) {
usb_remove_disk();
usb_msd_free();
}
#endif
#if TCFG_USB_SLAVE_AUDIO_ENABLE
usb_audio_demo_exit();
#endif
usb_device_mode(usbfd, 0);
}
void usb_stop()
{
log_info("App Stop - usb");
usb_pause();
usb_sie_close(usbfd);
}
#if TCFG_USB_CDC_BACKGROUND_RUN
void usb_cdc_background_run()
{
g_printf("CDC is running in the background");
usb_device_mode(0, CDC_CLASS);
cdc_set_wakeup_handler(usb_cdc_wakeup);
}
#endif
int pc_device_event_handler(struct sys_event *event)
{
if ((int)event->arg != DEVICE_EVENT_FROM_OTG) {
return false;
}
int switch_app_case = false;
const char *usb_msg = (const char *)event->u.dev.value;
log_debug("usb event : %d DEVICE_EVENT_FROM_OTG %s", event->u.dev.event, usb_msg);
if (usb_msg[0] == 's') {
if (event->u.dev.event == DEVICE_EVENT_IN) {
log_info("usb %c online", usb_msg[2]);
usbfd = usb_msg[2] - '0';
#if USB_PC_NO_APP_MODE
usb_start();
#elif TCFG_USB_DM_MULTIPLEX_WITH_SD_DAT0
#if TCFG_USB_CDC_BACKGROUND_RUN
mult_sdio_suspend();
usb_cdc_background_run();
switch_app_case = 0;
#else
usb_otg_suspend(0, OTG_KEEP_STATE);
mult_sdio_suspend();
usb_pause();
mult_sdio_resume();
switch_app_case = 0;
#endif//TCFG_USB_CDC_BACKGROUND_RUN
#else
#if (TWFG_APP_POWERON_IGNORE_DEV && TCFG_USB_CDC_BACKGROUND_RUN && TCFG_PC_ENABLE)
if (jiffies_to_msecs(jiffies) < TWFG_APP_POWERON_IGNORE_DEV) {
usb_cdc_background_run();
switch_app_case = 0;
} else {
usb_pause();
switch_app_case = 1;
}
#elif (!TCFG_PC_ENABLE)
usb_cdc_background_run();
switch_app_case = 0;
#elif (TWFG_APP_POWERON_IGNORE_DEV == 0)
usb_pause();
switch_app_case = 1;
#else
usb_pause();
switch_app_case = 1;
#endif
#endif
} else if (event->u.dev.event == DEVICE_EVENT_OUT) {
log_info("usb %c offline", usb_msg[2]);
switch_app_case = 2;
#ifdef USB_PC_NO_APP_MODE
usb_stop();
#else
#ifdef CONFIG_SOUNDBOX
if (!app_check_curr_task(APP_PC_TASK)) {
#else
if (!app_cur_task_check(APP_NAME_PC)) {
#endif
#if TCFG_USB_DM_MULTIPLEX_WITH_SD_DAT0
mult_sdio_suspend();
#endif
usb_stop();
#if TCFG_USB_DM_MULTIPLEX_WITH_SD_DAT0
mult_sdio_resume();
#endif
}
#endif
}
}
return switch_app_case;
}
#ifdef USB_PC_NO_APP_MODE
void usbstack_init()
{
register_sys_event_handler(SYS_DEVICE_EVENT, DEVICE_EVENT_FROM_OTG, 2,
pc_device_event_handler);
}
void usbstack_exit()
{
unregister_sys_event_handler(pc_device_event_handler);
}
#endif
#endif