Files
2025-12-03 11:12:34 +08:00

311 lines
9.2 KiB
C

#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".usb.data.bss")
#pragma data_seg(".usb.data")
#pragma code_seg(".usb.text")
#pragma const_seg(".usb.text.const")
#pragma str_literal_override(".usb.text.const")
#endif
#include "system/includes.h"
#include "system/event.h"
#include "os/os_api.h"
#include "app_main.h"
#if USB_PC_NO_APP_MODE == 0
#include "app_task.h"
#endif
#include "usb/usb_config.h"
#include "usb/usb_task.h"
#include "usb/device/usb_stack.h"
#include "usb/host/usb_host.h"
#include "usb/otg.h"
#if TCFG_USB_SLAVE_MSD_ENABLE
#include "usb/device/msd.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
#if TCFG_HOST_UVC_ENABLE
#include "uvc_device.h"
/* #include "usb/host/host_uvc.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"
#if TCFG_USB_SLAVE_ENABLE || TCFG_USB_HOST_ENABLE
/************************** otg data****************************/
#if TCFG_OTG_MODE
struct otg_dev_data otg_data = {
.usb_dev_en = TCFG_OTG_USB_DEV_EN,
.slave_online_cnt = TCFG_OTG_SLAVE_ONLINE_CNT,
.slave_offline_cnt = TCFG_OTG_SLAVE_OFFLINE_CNT,
.host_online_cnt = TCFG_OTG_HOST_ONLINE_CNT,
.host_offline_cnt = TCFG_OTG_HOST_OFFLINE_CNT,
.detect_mode = TCFG_OTG_MODE,
.detect_time_interval = TCFG_OTG_DET_INTERVAL,
};
#endif
extern void usb_cdc_background_run(const usb_dev usbfd);
extern int usb_cdc_background_standby(const usb_dev usbfd);
#include "jlui_app/ui_style.h"
#include "ui/ui_api.h"
u8 msd_in_task;
u8 msd_run_reset;
static OS_SEM msg_sem;
static void usb_task(void *p)
{
int ret;
int msg[16];
int from, event;
char *usb_msg;
usb_dev usb_id;
//cppcheck-suppress unusedVariable
struct device *dev;
u8 disk_msg = 0;
#if USB_EPBUF_ALLOC_USE_LBUF
extern int usb_memory_init(void);
usb_memory_init();
#endif
#if TCFG_OTG_MODE
extern int usb_otg_init(const struct dev_node * node, void *arg);
usb_otg_init(NULL, &otg_data);
#endif
r_printf("usb_task enter\n");
/* ASSERT(TCFG_PSRAM_DEV_ENABLE);//need to enable psram */
while (1) {
ret = os_taskq_pend("taskq", msg, ARRAY_SIZE(msg));
if (ret != OS_TASKQ) {
continue;
}
if (msg[0] != Q_MSG) {
continue;
}
g_printf("msg1 = %d\n", msg[1]);
switch (msg[1]) {
case USBSTACK_OTG_MSG:
from = msg[2];
event = msg[3];
usb_msg = (char *)msg[4];
if (from == DEVICE_EVENT_FROM_OTG) {
usb_id = usb_msg[2] - '0';
if (usb_msg[0] == 's') {
#if TCFG_USB_SLAVE_ENABLE
if (event == DEVICE_EVENT_IN) {
#if USB_PC_NO_APP_MODE
usb_start(usb_id);
#else
#if TCFG_USB_CDC_BACKGROUND_RUN
ret = usb_cdc_background_standby(usb_id);
#else
ret = usb_standby(usb_id);
#endif
//如果需要切入pc模式,将otg事件分发给app mode
if (ret) {
usb_driver_event_to_user(from, event, usb_msg);
}
#endif
} else if (event == DEVICE_EVENT_OUT) {
#if USB_PC_NO_APP_MODE
usb_stop(usb_id);
#else
usb_driver_event_to_user(from, event, usb_msg);
#endif
}
#endif
} else if (usb_msg[0] == 'h') {
#if TCFG_USB_HOST_ENABLE
if (event == DEVICE_EVENT_IN) {
#if TCFG_USB_DM_MULTIPLEX_WITH_SD_DAT0
mult_usb_mount_before(usb_id);
#endif
//cppcheck-suppress unreadVariable
ret = usb_host_mount(usb_id,
TCFG_USB_HOST_MOUNT_RETRY,
TCFG_USB_HOST_MOUNT_RESET,
TCFG_USB_HOST_MOUNT_TIMEOUT);
#if TCFG_USB_DM_MULTIPLEX_WITH_SD_DAT0
mult_usb_online_mount_after(usb_id, ret);
#endif
} else if (event == DEVICE_EVENT_OUT) {
usb_host_unmount(usb_id);
}
#endif
}
}
break;
#if TCFG_USB_SLAVE_ENABLE
case USBSTACK_START:
usb_id = msg[2];
#if TCFG_USB_CDC_BACKGROUND_RUN
usb_stop(usb_id);
#endif
usb_start(usb_id);
os_sem_post(&msg_sem);
break;
case USBSTACK_PAUSE:
usb_id = msg[2];
usb_pause(usb_id);
#if TCFG_USB_CDC_BACKGROUND_RUN
usb_cdc_background_run(usb_id);
#endif
os_sem_post(&msg_sem);
break;
case USBSTACK_STOP:
usb_id = msg[2];
usb_stop(usb_id);
os_sem_post(&msg_sem);
break;
#if TCFG_USB_SLAVE_MSD_ENABLE
case USBSTACK_MSD_RUN:
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;
break;
#endif
#if TCFG_USB_CDC_BACKGROUND_RUN
case USBSTACK_CDC_BACKGROUND:
usb_id = msg[2];
usb_cdc_background_run(usb_id);
os_sem_post(&msg_sem);
break;
#endif
#endif
#if TCFG_USB_HOST_ENABLE
case USBSTACK_HOST_MSG:
from = DEVICE_EVENT_FROM_USB_HOST;
event = msg[2];
usb_msg = (char *)msg[3];
if (!strncmp(usb_msg, "udisk", 5)) {
if (event == DEVICE_EVENT_IN) {
dev = dev_open(usb_msg, NULL);
if (dev) {
dev_close(dev);
disk_msg = 1;
} else {
disk_msg = 0;
}
} else if (event == DEVICE_EVENT_OUT) {
} else if (event == DEVICE_EVENT_CHANGE) {
}
//只有U盘尝试open成功才将usb host事件分发给app mode
//offline事件同理,尝试打开不成功则不分发事件
if (disk_msg) {
usb_driver_event_to_user(from, event, usb_msg);
}
}
#if TCFG_HOST_UVC_ENABLE
r_printf("USBSTACK_HOST_MSG: %s, event: %d\n", usb_msg, event);
if (!strncmp((const char *)usb_msg, "uvc", 3)) {
if (event == DEVICE_EVENT_IN) {
/* int sub_id = ((const char *)event->value)[3] - '0'; */
extern int usb_host_video_init(const usb_dev usb_id, const u8 sub_id);
usb_host_video_init(usb_id, usb_id);
extern int video_uvc_jpeg_stream_open(u16 width, u16 height);
video_uvc_jpeg_stream_open(640, 480);
UI_HIDE_CURR_WINDOW();
UI_SHOW_WINDOW(ID_WINDOW_UVC);
} else if (event == DEVICE_EVENT_OUT) {
extern int uvc_host_camera_out(const usb_dev usb_id);
extern int video_uvc_jpeg_stream_close();
video_uvc_jpeg_stream_close();
uvc_host_camera_out(usb_id);
usb_driver_event_to_user(from, event, usb_msg);
extern void jlset_uvc_status(u8 status);
jlset_uvc_status(0);//退出后清除状态
UI_HIDE_CURR_WINDOW();
UI_SHOW_WINDOW(ID_WINDOW_DIAL);
}
}
#endif
break;
case USBSTACK_HOST_REMOUNT:
usb_id = ((int *)msg[2])[0];
ret = usb_host_remount(usb_id, TCFG_USB_HOST_MOUNT_RETRY, TCFG_USB_HOST_MOUNT_RESET, TCFG_USB_HOST_MOUNT_TIMEOUT, 0);
((int *)msg[2])[1] = ret;
os_sem_post(&msg_sem);
break;
#if TCFG_USB_DM_MULTIPLEX_WITH_SD_DAT0
case USBSTACK_HOST_MOUNT_AFTER:
usb_id = ((int *)msg[2])[0];
ret = ((int *)msg[2])[1];
mult_usb_online_mount_after(usb_id, ret);
os_sem_post(&msg_sem);
break;
case USBSTACK_HOST_UNMOUNT_AFTER:
usb_id = ((int *)msg[2])[0];
ret = ((int *)msg[2])[1];
mult_usb_mount_offline(usb_id);
os_sem_post(&msg_sem);
break;
#endif
#endif
default:
break;
}
}
}
static int usb_stack_init(void)
{
r_printf("%s()", __func__);
int err;
os_sem_create(&msg_sem, 0);
err = task_create(usb_task, NULL, USB_TASK_NAME);
if (err != OS_NO_ERR) {
r_printf("usb_msd task creat fail %x\n", err);
}
return 0;
}
late_initcall(usb_stack_init);
void usb_message_to_stack(int msg, void *arg, u8 sync)
{
//先将sem清零0,否则当sync为0时不会pend,另一边post会使counter累加
os_sem_set(&msg_sem, 0);
os_taskq_post_msg(USB_TASK_NAME, 2, msg, arg);
if (sync) {
os_sem_pend(&msg_sem, 200);
}
}
#endif