/** * @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 "os/os_api.h" #include "event/device_event.h" #include "sdio/sdmmc.h" #if TCFG_USB_SLAVE_ENABLE #if USB_PC_NO_APP_MODE == 1 #include "app_task.h" #include "app_charge.h" #include "asm/charge.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_NAME0 "usb_msd0" #define USB_TASK_NAME1 "usb_msd1" #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 OS_MUTEX msd_mutex[USB_MAX_HW_NUM];//SEC(.usb_g_bss); static u8 msd_in_task[USB_MAX_HW_NUM]; static u8 msd_run_reset[USB_MAX_HW_NUM]; static void usb_task(void *p) { usb_dev usbfd = (usb_dev)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[usbfd], 0); msd_in_task[usbfd] = 1; #if TCFG_USB_APPLE_DOCK_EN apple_mfi_link((void *)msg[2]); #else USB_MassStorage((void *)msg[2]); #endif if (msd_run_reset[usbfd]) { msd_reset((struct usb_device_t *)msg[2], 0); msd_run_reset[usbfd] = 0; } msd_in_task[usbfd] = 0; os_mutex_post(&msd_mutex[usbfd]); 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[usbfd], 0); // msd_reset((struct usb_device_t *)msg[2], (u32)msg[3]); // os_mutex_post(&msd_mutex[usbfd]); // break; #endif default: break; } } } static void usb_msd_wakeup(struct usb_device_t *usb_device) { const usb_dev usb_id = usb_device2id(usb_device); if (!usb_id) { os_taskq_post_msg(USB_TASK_NAME0, 2, USBSTACK_MSD_RUN, usb_device); } else { os_taskq_post_msg(USB_TASK_NAME1, 2, USBSTACK_MSD_RUN, usb_device); } } static void usb_msd_reset_wakeup(struct usb_device_t *usb_device, u32 itf_num) { const usb_dev usb_id = usb_device2id(usb_device); /* os_taskq_post_msg(USB_TASK_NAME, 3, USBSTACK_MSD_RESET, usb_device, itf_num); */ if (msd_in_task[usb_id]) { msd_run_reset[usb_id] = 1; } else { #if TCFG_USB_SLAVE_MSD_ENABLE msd_reset(usb_device, 0); #endif } } static void usb_msd_init(const usb_dev usbfd) { /* r_printf("%s()", __func__); */ int err; os_mutex_create(&msd_mutex[usbfd]); if (!usbfd) { err = task_create(usb_task, (void *)usbfd, USB_TASK_NAME0); } else { err = task_create(usb_task, (void *)usbfd, USB_TASK_NAME1); } if (err != OS_NO_ERR) { r_printf("usb_msd task creat fail %x\n", err); } } static void usb_msd_free(const usb_dev usbfd) { /* r_printf("%s()", __func__); */ os_mutex_del(&msd_mutex[usbfd], 0); int err; OS_SEM sem; os_sem_create(&sem, 0); if (!usbfd) { os_taskq_post_msg(USB_TASK_NAME0, 2, USBSTACK_MSD_RELASE, (int)&sem); } else { os_taskq_post_msg(USB_TASK_NAME1, 2, USBSTACK_MSD_RELASE, (int)&sem); } os_sem_pend(&sem, 0); if (!usbfd) { err = task_kill(USB_TASK_NAME0); } else { err = task_kill(USB_TASK_NAME1); } 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) { #ifdef PRODUCT_TEST_ENABLE //进入PRODUCT_MODE后,将占用CDC数据接收通道 u8 product_tool_cdc_post(void); if (product_tool_cdc_post()) { return; } #endif //先post到任务,由任务调用cdc_read_data()读取再执行后续工作 struct device_event e = {0}; const usb_dev usb_id = usb_device2id(usb_device); e.value = usb_id; device_event_notify(DEVICE_EVENT_FROM_CFG_TOOL, &e); } #endif void usb_start(const usb_dev usbfd) { #if TCFG_USB_SLAVE_AUDIO_ENABLE usb_audio_demo_init(); #endif #ifdef USB_DEVICE_CLASS_CONFIG #if (defined USB_DEVICE_CLASS_CONFIG_2_0) && (USB_DEVICE_CLASS_CONFIG_2_0 != 0) if (usbfd != 0) { g_printf("USB_DEVICE_CLASS_CONFIG:%x", USB_DEVICE_CLASS_CONFIG_2_0); usb_device_mode(usbfd, USB_DEVICE_CLASS_CONFIG_2_0); } else { g_printf("USB_DEVICE_CLASS_CONFIG:%x", USB_DEVICE_CLASS_CONFIG); usb_device_mode(usbfd, USB_DEVICE_CLASS_CONFIG); } #else g_printf("USB_DEVICE_CLASS_CONFIG:%x", USB_DEVICE_CLASS_CONFIG); 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) #ifdef CONFIG_DMSDX_ENABLE msd_register_disk(usbfd, "sd0.0", NULL); msd_register_disk(usbfd, "sd0.1", NULL); #else msd_register_disk(usbfd, "sd0", NULL); #endif #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) #ifdef CONFIG_DMSDX_ENABLE msd_register_disk(usbfd, "sd1.0", NULL); msd_register_disk(usbfd, "sd1.1", NULL); #else msd_register_disk(usbfd, "sd1", NULL); #endif #endif #if TCFG_NOR_FAT msd_register_disk(usbfd, "fat_nor", NULL); #endif #if TCFG_VIR_UDISK_ENABLE msd_register_disk(usbfd, "vir_udisk", NULL); #endif #ifdef TCFG_EXTFLASH_UDISK_ENABLE msd_register_disk(usbfd, "extflash", NULL); #endif msd_set_wakeup_handle(usbfd, usb_msd_wakeup); msd_set_reset_wakeup_handle(usbfd, usb_msd_reset_wakeup); usb_msd_init(usbfd); #endif #if TCFG_USB_SLAVE_CDC_ENABLE cdc_set_wakeup_handler(usbfd, usb_cdc_wakeup); #endif #if TCFG_USB_SLAVE_HID_ENABLE #if USB_HID_KEYBOARD_ENABLE extern u8 *hid_keyboard_get_report_desc(); extern u32 hid_keyboard_get_report_desc_size(); extern int hid_keyboard_output(u8 * buf, u32 len); extern void hid_keyboard_set_usb_dev(usb_dev usb_id); hid_set_report_desc(usbfd, hid_keyboard_get_report_desc(), hid_keyboard_get_report_desc_size()); hid_set_output_handle(usbfd, hid_keyboard_output); hid_keyboard_set_usb_dev(usbfd); #elif USB_HID_POS_ENABLE extern u8 *hid_pos_get_report_desc(); extern u32 hid_pos_get_report_desc_size(); extern int hid_pos_receive(u8 * buf, u32 len); extern int hid_pos_open(usb_dev usb_id); hid_set_report_desc(usbfd, hid_pos_get_report_desc(), hid_pos_get_report_desc_size()); hid_set_output_handle(usbfd, hid_pos_receive); hid_pos_open(usbfd); #endif hid_control(usbfd, 1); #endif } static void usb_remove_disk(const usb_dev usbfd) { #if TCFG_USB_SLAVE_MSD_ENABLE os_mutex_pend(&msd_mutex[usbfd], 0); msd_unregister_all(usbfd); os_mutex_post(&msd_mutex[usbfd]); #endif } void usb_pause(const usb_dev usbfd) { log_info("usb pause"); usb_sie_disable(usbfd); #if TCFG_USB_SLAVE_MSD_ENABLE if (msd_set_wakeup_handle(usbfd, NULL)) { usb_remove_disk(usbfd); usb_msd_free(usbfd); } #endif #if TCFG_USB_SLAVE_AUDIO_ENABLE usb_audio_demo_exit(); #endif #if TCFG_USB_SLAVE_HID_ENABLE hid_control(usbfd, 0); hid_set_report_desc(usbfd, NULL, 0); hid_set_output_handle(usbfd, NULL); #if USB_HID_POS_ENABLE extern void hid_pos_close(usb_dev usb_id); hid_pos_close(usbfd); #endif #endif usb_device_mode(usbfd, 0); } void usb_stop(const usb_dev usbfd) { log_info("App Stop - usb"); usb_pause(usbfd); usb_sie_close(usbfd); } int pc_device_event_handler(struct sys_event *e) { if (e->from != DEVICE_EVENT_FROM_OTG) { return false; } struct device_event *event = (struct device_event *)e->payload; int switch_app_case = false; const char *usb_msg = (const char *)event->value; log_debug("usb event : %d DEVICE_EVENT_FROM_OTG %s", event->event, usb_msg); usb_dev usbfd = 0; if (usb_msg[0] == 's') { if (event->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(usbfd); #elif TCFG_USB_DM_MULTIPLEX_WITH_SD_DAT0 usb_otg_suspend(0, OTG_KEEP_STATE); mult_sdio_suspend(); usb_pause(usbfd); mult_sdio_resume(); #else usb_pause(usbfd); #endif switch_app_case = 1; } else if (event->event == DEVICE_EVENT_OUT) { log_info("usb %c offline", usb_msg[2]); usbfd = usb_msg[2] - '0'; switch_app_case = 2; #if USB_PC_NO_APP_MODE usb_stop(usbfd); #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(usbfd); #if TCFG_USB_DM_MULTIPLEX_WITH_SD_DAT0 mult_sdio_resume(); #endif } #endif } } return switch_app_case; } #endif