@@ -151,7 +151,7 @@ typedef struct _usb_cfg_hid_descr_t
|
||||
usb_cfg_descr_t config;
|
||||
usb_inter_descr_t interface;
|
||||
usb_hid_descr_t hid;
|
||||
usb_ep_descr_t endpoint[2];
|
||||
usb_ep_descr_t endpoint[1];
|
||||
} __attribute__((packed)) usb_cfg_hid_descr_t;
|
||||
|
||||
typedef struct _usb_dev_bot_t
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* USB driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019-2020 CTCaer
|
||||
* Copyright (c) 2019-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -409,10 +409,10 @@ static usb_cfg_hid_descr_t usb_configuration_descriptor_hid_jc =
|
||||
.interface.bDescriptorType = USB_DESCRIPTOR_INTERFACE,
|
||||
.interface.bInterfaceNumber = 0,
|
||||
.interface.bAlternateSetting = 0,
|
||||
.interface.bNumEndpoints = 2,
|
||||
.interface.bNumEndpoints = 1,
|
||||
.interface.bInterfaceClass = 0x03, // Human Interface Device Class.
|
||||
.interface.bInterfaceSubClass = 0x00, // SCSI Transparent Command Set.
|
||||
.interface.bInterfaceProtocol = 0x00, // Bulk-Only Transport.
|
||||
.interface.bInterfaceSubClass = 0x00, // No Subclass.
|
||||
.interface.bInterfaceProtocol = 0x00, // None.
|
||||
.interface.iInterface = 0x00,
|
||||
|
||||
.hid.bLength = 9,
|
||||
@@ -430,14 +430,6 @@ static usb_cfg_hid_descr_t usb_configuration_descriptor_hid_jc =
|
||||
.endpoint[0].bmAttributes = USB_EP_TYPE_INTR,
|
||||
.endpoint[0].wMaxPacketSize = 0x200,
|
||||
.endpoint[0].bInterval = 4, // 8ms on HS.
|
||||
|
||||
/* Endpoint descriptor structure EP1 OUT */
|
||||
.endpoint[1].bLength = 7,
|
||||
.endpoint[1].bDescriptorType = USB_DESCRIPTOR_ENDPOINT,
|
||||
.endpoint[1].bEndpointAddress = 0x01, // USB_EP_ADDR_BULK_OUT.
|
||||
.endpoint[1].bmAttributes = USB_EP_TYPE_INTR,
|
||||
.endpoint[1].wMaxPacketSize = 0x200,
|
||||
.endpoint[1].bInterval = 4 // 8ms on HS.
|
||||
};
|
||||
|
||||
static u8 usb_vendor_string_descriptor_hid[22] =
|
||||
@@ -478,10 +470,10 @@ static usb_cfg_hid_descr_t usb_configuration_descriptor_hid_touch =
|
||||
.interface.bDescriptorType = USB_DESCRIPTOR_INTERFACE,
|
||||
.interface.bInterfaceNumber = 0,
|
||||
.interface.bAlternateSetting = 0,
|
||||
.interface.bNumEndpoints = 2,
|
||||
.interface.bNumEndpoints = 1,
|
||||
.interface.bInterfaceClass = 0x03, // Human Interface Device Class.
|
||||
.interface.bInterfaceSubClass = 0x00, // SCSI Transparent Command Set.
|
||||
.interface.bInterfaceProtocol = 0x00, // Bulk-Only Transport.
|
||||
.interface.bInterfaceSubClass = 0x00, // No Subclass.
|
||||
.interface.bInterfaceProtocol = 0x00, // None.
|
||||
.interface.iInterface = 0x00,
|
||||
|
||||
.hid.bLength = 9,
|
||||
@@ -499,14 +491,6 @@ static usb_cfg_hid_descr_t usb_configuration_descriptor_hid_touch =
|
||||
.endpoint[0].bmAttributes = USB_EP_TYPE_INTR,
|
||||
.endpoint[0].wMaxPacketSize = 0x200,
|
||||
.endpoint[0].bInterval = 3, // 4ms on HS.
|
||||
|
||||
/* Endpoint descriptor structure EP1 OUT */
|
||||
.endpoint[1].bLength = 7,
|
||||
.endpoint[1].bDescriptorType = USB_DESCRIPTOR_ENDPOINT,
|
||||
.endpoint[1].bEndpointAddress = 0x01, // USB_EP_ADDR_BULK_OUT.
|
||||
.endpoint[1].bmAttributes = USB_EP_TYPE_INTR,
|
||||
.endpoint[1].wMaxPacketSize = 0x200,
|
||||
.endpoint[1].bInterval = 3 // 4ms on HS.
|
||||
};
|
||||
|
||||
usb_desc_t usb_gadget_ums_descriptors =
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* USB Gadget HID driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019-2022 CTCaer
|
||||
* Copyright (c) 2019-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -80,6 +80,8 @@ enum {
|
||||
static jc_cal_t jc_cal_ctx;
|
||||
static usb_ops_t usb_ops;
|
||||
|
||||
static void *rpt_buffer = (u8 *)USB_EP_BULK_IN_BUF_ADDR;
|
||||
|
||||
static bool _jc_calibration(const jc_gamepad_rpt_t *jc_pad)
|
||||
{
|
||||
// Calibrate left stick.
|
||||
@@ -347,10 +349,10 @@ static bool _fts_touch_read(touchpad_report_t *rpt)
|
||||
|
||||
static u8 _hid_transfer_start(usb_ctxt_t *usbs, u32 len)
|
||||
{
|
||||
u8 status = usb_ops.usb_device_ep1_in_write((u8 *)USB_EP_BULK_IN_BUF_ADDR, len, NULL, USB_XFER_SYNCED_CMD);
|
||||
u8 status = usb_ops.usb_device_ep1_in_write(rpt_buffer, len, NULL, USB_XFER_SYNCED_CMD);
|
||||
if (status == USB_ERROR_XFER_ERROR)
|
||||
{
|
||||
usbs->set_text(usbs->label, "#FFDD00 错误:#EP IN传输!");
|
||||
usbs->set_text(usbs->label, "#FFDD00 错误:#端口IN传输错误!");
|
||||
if (usb_ops.usbd_flush_endpoint)
|
||||
usb_ops.usbd_flush_endpoint(USB_EP_BULK_IN);
|
||||
}
|
||||
@@ -364,12 +366,12 @@ static u8 _hid_transfer_start(usb_ctxt_t *usbs, u32 len)
|
||||
|
||||
static bool _hid_poll_jc(usb_ctxt_t *usbs)
|
||||
{
|
||||
int res = _jc_poll((gamepad_report_t *)USB_EP_BULK_IN_BUF_ADDR);
|
||||
int res = _jc_poll(rpt_buffer);
|
||||
if (res == INPUT_POLL_EXIT)
|
||||
return true;
|
||||
|
||||
// Send HID report.
|
||||
if (res == INPUT_POLL_HAS_PACKET)
|
||||
if (res == INPUT_POLL_HAS_PACKET || usbs->idle)
|
||||
if (_hid_transfer_start(usbs, sizeof(gamepad_report_t)))
|
||||
return true; // EP Error.
|
||||
|
||||
@@ -378,7 +380,7 @@ static bool _hid_poll_jc(usb_ctxt_t *usbs)
|
||||
|
||||
static bool _hid_poll_touch(usb_ctxt_t *usbs)
|
||||
{
|
||||
_fts_touch_read((touchpad_report_t *)USB_EP_BULK_IN_BUF_ADDR);
|
||||
_fts_touch_read(rpt_buffer);
|
||||
|
||||
// Send HID report.
|
||||
if (_hid_transfer_start(usbs, sizeof(touchpad_report_t)))
|
||||
@@ -399,6 +401,10 @@ int usb_device_gadget_hid(usb_ctxt_t *usbs)
|
||||
else
|
||||
xusb_device_get_ops(&usb_ops);
|
||||
|
||||
// Always push packets by default.
|
||||
//! TODO: For now only per polling rate or on change is supported.
|
||||
usbs->idle = 1;
|
||||
|
||||
if (usbs->type == USB_HID_GAMEPAD)
|
||||
{
|
||||
polling_time = 15000;
|
||||
@@ -410,7 +416,7 @@ int usb_device_gadget_hid(usb_ctxt_t *usbs)
|
||||
gadget_type = USB_GADGET_HID_TOUCHPAD;
|
||||
}
|
||||
|
||||
usbs->set_text(usbs->label, "#C7EA46 状态:#USB1已开启");
|
||||
usbs->set_text(usbs->label, "#C7EA46 状态:#USB已启动");
|
||||
|
||||
if (usb_ops.usb_device_init())
|
||||
{
|
||||
@@ -418,24 +424,32 @@ int usb_device_gadget_hid(usb_ctxt_t *usbs)
|
||||
return 1;
|
||||
}
|
||||
|
||||
usbs->set_text(usbs->label, "#C7EA46 状态:#等待连接中");
|
||||
usbs->set_text(usbs->label, "#C7EA46 状态:#正在等待连接");
|
||||
|
||||
// Initialize Control Endpoint.
|
||||
if (usb_ops.usb_device_enumerate(gadget_type))
|
||||
goto error;
|
||||
|
||||
usbs->set_text(usbs->label, "#C7EA46 状态:#等待HID上报请求中");
|
||||
usbs->set_text(usbs->label, "#C7EA46 状态:#正在等待HID报告请求");
|
||||
|
||||
if (usb_ops.usb_device_class_send_hid_report())
|
||||
u32 rpt_size = usbs->type == USB_HID_GAMEPAD ? sizeof(gamepad_report_t) : sizeof(touchpad_report_t);
|
||||
if (usb_ops.usb_device_class_send_hid_report(rpt_buffer, rpt_size))
|
||||
goto error;
|
||||
|
||||
usbs->set_text(usbs->label, "#C7EA46 状态:#HID模拟已开启");
|
||||
usbs->set_text(usbs->label, "#C7EA46 状态:#HID仿真已启动");
|
||||
|
||||
u32 timer_sys = get_tmr_ms() + 5000;
|
||||
while (true)
|
||||
{
|
||||
u32 timer = get_tmr_us();
|
||||
|
||||
// Check for suspended USB in case the cable was pulled.
|
||||
if (usb_ops.usb_device_get_suspended())
|
||||
break; // Disconnected.
|
||||
|
||||
// Handle control endpoint.
|
||||
usb_ops.usbd_handle_ep0_ctrl_setup(&usbs->idle);
|
||||
|
||||
// Parse input device.
|
||||
if (usbs->type == USB_HID_GAMEPAD)
|
||||
{
|
||||
@@ -448,13 +462,6 @@ int usb_device_gadget_hid(usb_ctxt_t *usbs)
|
||||
break;
|
||||
}
|
||||
|
||||
// Check for suspended USB in case the cable was pulled.
|
||||
if (usb_ops.usb_device_get_suspended())
|
||||
break; // Disconnected.
|
||||
|
||||
// Handle control endpoint.
|
||||
usb_ops.usbd_handle_ep0_ctrl_setup();
|
||||
|
||||
// Wait max gadget timing.
|
||||
timer = get_tmr_us() - timer;
|
||||
if (timer < polling_time)
|
||||
@@ -467,11 +474,11 @@ int usb_device_gadget_hid(usb_ctxt_t *usbs)
|
||||
}
|
||||
}
|
||||
|
||||
usbs->set_text(usbs->label, "#C7EA46 状态:#HID已结束");
|
||||
usbs->set_text(usbs->label, "#C7EA46 状态:#HID已结束");
|
||||
goto exit;
|
||||
|
||||
error:
|
||||
usbs->set_text(usbs->label, "#FFDD00 错误:#超时或已取消");
|
||||
usbs->set_text(usbs->label, "#FFDD00 错误:#超时或已被取消");
|
||||
res = 1;
|
||||
|
||||
exit:
|
||||
|
||||
@@ -28,11 +28,10 @@
|
||||
#include <soc/t210.h>
|
||||
#include <storage/sd.h>
|
||||
#include <storage/sdmmc.h>
|
||||
#include <storage/emmc.h>
|
||||
#include <storage/sdmmc_driver.h>
|
||||
#include <storage/emmc.h>
|
||||
#include <utils/btn.h>
|
||||
#include <utils/sprintf.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
#include <memory_map.h>
|
||||
|
||||
@@ -287,7 +286,7 @@ static void raise_exception(usbd_gadget_ums_t *ums, enum ums_state new_state)
|
||||
|
||||
static void _handle_ep0_ctrl(usbd_gadget_ums_t *ums)
|
||||
{
|
||||
if (usb_ops.usbd_handle_ep0_ctrl_setup())
|
||||
if (usb_ops.usbd_handle_ep0_ctrl_setup(NULL))
|
||||
raise_exception(ums, UMS_STATE_PROTOCOL_RESET);
|
||||
}
|
||||
|
||||
@@ -328,11 +327,11 @@ static void _transfer_start(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt, u32
|
||||
|
||||
if (bulk_ctxt->bulk_in_status == USB_ERROR_XFER_ERROR)
|
||||
{
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#EP IN传输!");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#端口IN传输错误!");
|
||||
_flush_endpoint(bulk_ctxt->bulk_in);
|
||||
}
|
||||
else if (bulk_ctxt->bulk_in_status == USB2_ERROR_XFER_NOT_ALIGNED)
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#EP IN缓冲区未对齐");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#端口IN缓冲区未对齐!");
|
||||
|
||||
if (sync_timeout)
|
||||
bulk_ctxt->bulk_in_buf_state = BUF_STATE_EMPTY;
|
||||
@@ -345,11 +344,11 @@ static void _transfer_start(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt, u32
|
||||
|
||||
if (bulk_ctxt->bulk_out_status == USB_ERROR_XFER_ERROR)
|
||||
{
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#EP OUT传输!");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#端口OUT传输错误!");
|
||||
_flush_endpoint(bulk_ctxt->bulk_out);
|
||||
}
|
||||
else if (bulk_ctxt->bulk_out_status == USB2_ERROR_XFER_NOT_ALIGNED)
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#EP OUT缓冲区未对齐!");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#端口OUT缓冲区未对齐!");
|
||||
|
||||
if (sync_timeout)
|
||||
bulk_ctxt->bulk_out_buf_state = BUF_STATE_FULL;
|
||||
@@ -364,7 +363,7 @@ static void _transfer_out_big_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctx
|
||||
|
||||
if (bulk_ctxt->bulk_out_status == USB_ERROR_XFER_ERROR)
|
||||
{
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#EP OUT传输");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#端口OUT传输错误!");
|
||||
_flush_endpoint(bulk_ctxt->bulk_out);
|
||||
}
|
||||
|
||||
@@ -380,7 +379,7 @@ static void _transfer_finish(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt, u32
|
||||
|
||||
if (bulk_ctxt->bulk_in_status == USB_ERROR_XFER_ERROR)
|
||||
{
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#EP IN传输!");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#端口IN传输错误!");
|
||||
_flush_endpoint(bulk_ctxt->bulk_in);
|
||||
}
|
||||
|
||||
@@ -393,7 +392,7 @@ static void _transfer_finish(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt, u32
|
||||
|
||||
if (bulk_ctxt->bulk_out_status == USB_ERROR_XFER_ERROR)
|
||||
{
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#EP OUT传输!");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#端口OUT传输!");
|
||||
_flush_endpoint(bulk_ctxt->bulk_out);
|
||||
}
|
||||
|
||||
@@ -463,7 +462,7 @@ static int _scsi_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
}
|
||||
if (lba_offset >= ums->lun.num_sectors)
|
||||
{
|
||||
ums->set_text(ums->label, "#FF8000 警告:#读取 - 超出范围!已通知主机。");
|
||||
ums->set_text(ums->label, "#FF8000 警告:#读取超出范围!主机已通知。");
|
||||
ums->lun.sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
|
||||
|
||||
return UMS_RES_INVALID_ARG;
|
||||
@@ -515,7 +514,7 @@ static int _scsi_read(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
// If an error occurred, report it and its position.
|
||||
if (!amount)
|
||||
{
|
||||
ums->set_text(ums->label, "#FFDD00 错误:# SDMMC读取!");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#SDMMC读取失败!");
|
||||
ums->lun.sense_data = SS_UNRECOVERED_READ_ERROR;
|
||||
ums->lun.sense_data_info = lba_offset;
|
||||
ums->lun.info_valid = 1;
|
||||
@@ -553,7 +552,7 @@ static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
|
||||
if (ums->lun.ro)
|
||||
{
|
||||
ums->set_text(ums->label, "#FF8000 警告:#写入 - 只读!已通知主机。");
|
||||
ums->set_text(ums->label, "#FF8000 警告:#写入受阻 - 只读模式! 已通知主机。");
|
||||
ums->lun.sense_data = SS_WRITE_PROTECTED;
|
||||
|
||||
return UMS_RES_INVALID_ARG;
|
||||
@@ -577,7 +576,7 @@ static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
// Check that starting LBA is not past the end sector offset.
|
||||
if (lba_offset >= ums->lun.num_sectors)
|
||||
{
|
||||
ums->set_text(ums->label, "#FF8000 警告:#写入 - 超出范围!已通知主机。");
|
||||
ums->set_text(ums->label, "#FF8000 警告:#写入超出范围! 已通知主机。");
|
||||
ums->lun.sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
|
||||
|
||||
return UMS_RES_INVALID_ARG;
|
||||
@@ -599,7 +598,7 @@ static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
|
||||
if (usb_lba_offset >= ums->lun.num_sectors)
|
||||
{
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#写入 - 超出最后扇区!");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:# 写入超过最后一个扇区!");
|
||||
ums->lun.sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
|
||||
ums->lun.sense_data_info = usb_lba_offset;
|
||||
ums->lun.info_valid = 1;
|
||||
@@ -627,7 +626,7 @@ static int _scsi_write(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
ums->lun.sense_data_info = lba_offset;
|
||||
ums->lun.info_valid = 1;
|
||||
|
||||
s_printf(txt_buf, "#FFDD00 错误:#写入 - 通讯失败 %d!", bulk_ctxt->bulk_out_status);
|
||||
s_printf(txt_buf, "#FFDD00 错误:#写入通信失败 %d!", bulk_ctxt->bulk_out_status);
|
||||
ums->set_text(ums->label, txt_buf);
|
||||
break;
|
||||
}
|
||||
@@ -665,7 +664,7 @@ DPRINTF("file write %X @ %X\n", amount, lba_offset);
|
||||
// If an error occurred, report it and its position.
|
||||
if (!amount)
|
||||
{
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#SDMMC写入!");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#SDMMC写入失败!");
|
||||
ums->lun.sense_data = SS_WRITE_ERROR;
|
||||
ums->lun.sense_data_info = lba_offset;
|
||||
ums->lun.info_valid = 1;
|
||||
@@ -676,7 +675,7 @@ DPRINTF("file write %X @ %X\n", amount, lba_offset);
|
||||
// Did the host decide to stop early?
|
||||
if (bulk_ctxt->bulk_out_length_actual < bulk_ctxt->bulk_out_length)
|
||||
{
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#空写入");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#空写入!");
|
||||
ums->short_packet_received = 1;
|
||||
break;
|
||||
}
|
||||
@@ -692,7 +691,7 @@ static int _scsi_verify(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
u32 lba_offset = get_array_be_to_le32(&ums->cmnd[2]);
|
||||
if (lba_offset >= ums->lun.num_sectors)
|
||||
{
|
||||
ums->set_text(ums->label, "#FF8000 警告:#校验 - 超出范围!已通知主机。");
|
||||
ums->set_text(ums->label, "#FF8000 警告:#验证超出范围! 已通知主机。");
|
||||
ums->lun.sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
|
||||
|
||||
return UMS_RES_INVALID_ARG;
|
||||
@@ -731,7 +730,7 @@ DPRINTF("File read %X @ %X\n", amount, lba_offset);
|
||||
|
||||
if (!amount)
|
||||
{
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#文件检验!");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#文件验证失败!");
|
||||
ums->lun.sense_data = SS_UNRECOVERED_READ_ERROR;
|
||||
ums->lun.sense_data_info = lba_offset;
|
||||
ums->lun.info_valid = 1;
|
||||
@@ -764,7 +763,7 @@ static int _scsi_inquiry(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
switch (ums->lun.partition)
|
||||
{
|
||||
case 0:
|
||||
strcpy((char *)buf + strlen((char *)buf), "原始");
|
||||
strcpy((char *)buf + strlen((char *)buf), "RAW");
|
||||
break;
|
||||
case EMMC_GPP + 1:
|
||||
s_printf((char *)buf + strlen((char *)buf), "GPP");
|
||||
@@ -800,7 +799,7 @@ static int _scsi_inquiry(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
switch (ums->lun.partition)
|
||||
{
|
||||
case 0:
|
||||
s_printf((char *)buf, "%s", "SD卡原始分区");
|
||||
s_printf((char *)buf, "%s", "SD RAW");
|
||||
break;
|
||||
case EMMC_GPP + 1:
|
||||
s_printf((char *)buf, "%s%s",
|
||||
@@ -1060,7 +1059,7 @@ static int _scsi_start_stop(usbd_gadget_ums_t *ums)
|
||||
// Check if we are allowed to unload the media.
|
||||
if (ums->lun.prevent_medium_removal)
|
||||
{
|
||||
ums->set_text(ums->label, "#C7EA46 状态:#卸载尝试已被阻止");
|
||||
ums->set_text(ums->label, "#C7EA46 状态:#尝试卸载被阻止");
|
||||
ums->lun.sense_data = SS_MEDIUM_REMOVAL_PREVENTED;
|
||||
|
||||
return UMS_RES_INVALID_ARG;
|
||||
@@ -1468,7 +1467,7 @@ static int _finish_reply(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
{
|
||||
_set_ep_stall(bulk_ctxt->bulk_out);
|
||||
rc = _set_ep_stall(bulk_ctxt->bulk_in);
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#方向不明。两端EP已暂停!");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#方向未知。已停止两个端口!");
|
||||
} // Else do nothing.
|
||||
break;
|
||||
|
||||
@@ -1489,7 +1488,7 @@ static int _finish_reply(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
{
|
||||
_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED_DATA);
|
||||
rc = _set_ep_stall(bulk_ctxt->bulk_in);
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#数据残留。EP IN已停止!");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#残留。已停止端口IN!");
|
||||
}
|
||||
else
|
||||
rc = _pad_with_zeros(ums, bulk_ctxt);
|
||||
@@ -1562,7 +1561,7 @@ static int _received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
{
|
||||
if (usb_ops.usb_device_get_port_in_sleep())
|
||||
{
|
||||
ums->set_text(ums->label, "#C7EA46 状态:#EP已休眠");
|
||||
ums->set_text(ums->label, "#C7EA46 状态:#端口休眠中");
|
||||
ums->timeouts += 14;
|
||||
}
|
||||
else if (!ums->xusb) // Timeout only on USB2.
|
||||
@@ -1581,7 +1580,7 @@ static int _received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
|
||||
if (ums->lun.unmounted)
|
||||
{
|
||||
ums->set_text(ums->label, "#C7EA46 状态:#介质未挂载");
|
||||
ums->set_text(ums->label, "#C7EA46 状态:# 介质已卸载");
|
||||
ums->timeouts++;
|
||||
if (!bulk_ctxt->bulk_out_status)
|
||||
ums->timeouts += 3;
|
||||
@@ -1633,7 +1632,7 @@ static int _received_cbw(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
{
|
||||
_set_ep_stall(bulk_ctxt->bulk_out);
|
||||
_set_ep_stall(bulk_ctxt->bulk_in);
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#CBW未知 - 两端EP已停止!");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#CBW未知 - 已停止两个端口!");
|
||||
}
|
||||
|
||||
return UMS_RES_INVALID_ARG;
|
||||
@@ -1712,7 +1711,7 @@ static void _send_status(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
|
||||
|
||||
if (ums->phase_error)
|
||||
{
|
||||
ums->set_text(ums->label, "#FFDD00 错误:#相位错误!");
|
||||
ums->set_text(ums->label, "#FFDD00 错误:# 阶段性错误!");
|
||||
status = USB_STATUS_PHASE_ERROR;
|
||||
sd = SS_INVALID_COMMAND;
|
||||
}
|
||||
@@ -1826,7 +1825,7 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
|
||||
xusb_device_get_ops(&usb_ops);
|
||||
}
|
||||
|
||||
usbs->set_text(usbs->label, "#C7EA46 状态:#USB已开启");
|
||||
usbs->set_text(usbs->label, "#C7EA46 状态:#已启动USB");
|
||||
|
||||
if (usb_ops.usb_device_init())
|
||||
{
|
||||
@@ -1857,7 +1856,7 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
|
||||
ums.set_text = usbs->set_text;
|
||||
ums.system_maintenance = usbs->system_maintenance;
|
||||
|
||||
ums.set_text(ums.label, "#C7EA46 状态:#磁盘挂载中");
|
||||
ums.set_text(ums.label, "#C7EA46 状态:#挂载磁盘");
|
||||
|
||||
// Initialize sdmmc.
|
||||
if (usbs->type == MMC_SD)
|
||||
@@ -1888,18 +1887,18 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
|
||||
ums.lun.storage = &emmc_storage;
|
||||
}
|
||||
|
||||
ums.set_text(ums.label, "#C7EA46 状态:#连接等待中");
|
||||
ums.set_text(ums.label, "#C7EA46 状态:#正在等待连接");
|
||||
|
||||
// Initialize Control Endpoint.
|
||||
if (usb_ops.usb_device_enumerate(USB_GADGET_UMS))
|
||||
goto usb_enum_error;
|
||||
|
||||
ums.set_text(ums.label, "#C7EA46 状态:#LUN等待中");
|
||||
ums.set_text(ums.label, "#C7EA46 状态:#正在等待LUN");
|
||||
|
||||
if (usb_ops.usb_device_class_send_max_lun(0)) // One device for now.
|
||||
goto usb_enum_error;
|
||||
|
||||
ums.set_text(ums.label, "#C7EA46 状态:#UMS已开启");
|
||||
ums.set_text(ums.label, "#C7EA46 状态:#已启动UMS");
|
||||
|
||||
// If partition sectors are not set get them from hardware.
|
||||
if (!ums.lun.num_sectors)
|
||||
@@ -1920,7 +1919,7 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
|
||||
{
|
||||
// Check if we are allowed to unload the media.
|
||||
if (ums.lun.prevent_medium_removal)
|
||||
ums.set_text(ums.label, "#C7EA46 状态:#卸载尝试已被阻止");
|
||||
ums.set_text(ums.label, "#C7EA46 状态:#尝试卸载被阻止");
|
||||
else
|
||||
break;
|
||||
}
|
||||
@@ -1952,13 +1951,13 @@ int usb_device_gadget_ums(usb_ctxt_t *usbs)
|
||||
} while (ums.state != UMS_STATE_TERMINATED);
|
||||
|
||||
if (ums.lun.prevent_medium_removal)
|
||||
ums.set_text(ums.label, "#FFDD00 错误:#磁盘已未安全弹出");
|
||||
ums.set_text(ums.label, "#FFDD00 错误:#磁盘不安全弹出");
|
||||
else
|
||||
ums.set_text(ums.label, "#C7EA46 状态:#磁盘已弹出");
|
||||
goto exit;
|
||||
|
||||
usb_enum_error:
|
||||
ums.set_text(ums.label, "#FFDD00 错误:#超时或已取消!");
|
||||
ums.set_text(ums.label, "#FFDD00 错误:#超时或取消!");
|
||||
res = 1;
|
||||
|
||||
exit:
|
||||
|
||||
191
bdk/usb/usbd.c
191
bdk/usb/usbd.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Enhanced USB Device (EDCI) driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019-2024 CTCaer
|
||||
* Copyright (c) 2019-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -101,7 +101,11 @@ typedef struct _usbd_controller_t
|
||||
bool configuration_set;
|
||||
bool max_lun_set;
|
||||
bool bulk_reset_req;
|
||||
u32 intr_idle_rate;
|
||||
bool intr_idle_req;
|
||||
bool hid_report_sent;
|
||||
void *hid_rpt_buffer;
|
||||
u32 hid_rpt_size;
|
||||
u32 charger_detect;
|
||||
} usbd_controller_t;
|
||||
|
||||
@@ -881,7 +885,7 @@ int usbd_set_ep_stall(u32 endpoint, int ep_stall)
|
||||
return USB_RES_OK;
|
||||
}
|
||||
|
||||
static void _usbd_handle_get_class_request(bool *transmit_data, u8 *descriptor, int *size, bool *ep_stall)
|
||||
static void _usbd_handle_get_class_request(bool *transmit_data, u8 *desc, int *size, bool *ep_stall)
|
||||
{
|
||||
u8 _bRequest = usbd_otg->control_setup.bRequest;
|
||||
u16 _wIndex = usbd_otg->control_setup.wIndex;
|
||||
@@ -889,9 +893,9 @@ static void _usbd_handle_get_class_request(bool *transmit_data, u8 *descriptor,
|
||||
u16 _wLength = usbd_otg->control_setup.wLength;
|
||||
|
||||
bool valid_interface = _wIndex == usbd_otg->interface_num;
|
||||
bool valid_len = (_bRequest == USB_REQUEST_BULK_GET_MAX_LUN) ? 1 : 0;
|
||||
bool valid_val = (_bRequest >= USB_REQUEST_BULK_GET_MAX_LUN) ? (!_wValue) : true;
|
||||
|
||||
if (!valid_interface || _wValue != 0 || _wLength != valid_len)
|
||||
if (!valid_interface || !valid_val)
|
||||
{
|
||||
*ep_stall = true;
|
||||
return;
|
||||
@@ -899,23 +903,51 @@ static void _usbd_handle_get_class_request(bool *transmit_data, u8 *descriptor,
|
||||
|
||||
switch (_bRequest)
|
||||
{
|
||||
case USB_REQUEST_INTR_GET_REPORT:
|
||||
if (usbd_otg->hid_rpt_size != _wLength)
|
||||
break;
|
||||
|
||||
// _wValue unused as there's only one report type and id.
|
||||
*transmit_data = true;
|
||||
*size = usbd_otg->hid_rpt_size;
|
||||
memcpy(desc, usbd_otg->hid_rpt_buffer, usbd_otg->hid_rpt_size);
|
||||
return;
|
||||
|
||||
case USB_REQUEST_INTR_SET_IDLE:
|
||||
if (_wLength)
|
||||
break;
|
||||
|
||||
usbd_otg->intr_idle_rate = (_wValue & 0xFF) * 4 * 1000; // Only one interface so upper byte ignored.
|
||||
usbd_otg->intr_idle_req = true;
|
||||
_usbd_ep_ack(USB_EP_CTRL_IN);
|
||||
return; // DELAYED_STATUS;
|
||||
|
||||
case USB_REQUEST_BULK_RESET:
|
||||
if (_wLength)
|
||||
break;
|
||||
|
||||
_usbd_ep_ack(USB_EP_CTRL_IN);
|
||||
usbd_otg->bulk_reset_req = true;
|
||||
break; // DELAYED_STATUS;
|
||||
return; // DELAYED_STATUS;
|
||||
|
||||
case USB_REQUEST_BULK_GET_MAX_LUN:
|
||||
if (_wLength != 1)
|
||||
break;
|
||||
|
||||
*transmit_data = true;
|
||||
*size = 1;
|
||||
descriptor[0] = usbd_otg->max_lun; // Set 0 LUN for 1 drive supported.
|
||||
desc[0] = usbd_otg->max_lun; // Set 0 LUN for 1 drive supported.
|
||||
usbd_otg->max_lun_set = true;
|
||||
break;
|
||||
return;
|
||||
|
||||
default:
|
||||
*ep_stall = true;
|
||||
break;
|
||||
}
|
||||
|
||||
*ep_stall = true;
|
||||
}
|
||||
|
||||
static void _usbd_handle_get_descriptor(bool *transmit_data, void **descriptor, int *size, bool *ep_stall)
|
||||
static void _usbd_handle_get_descriptor(bool *transmit_data, void **desc, int *size, bool *ep_stall)
|
||||
{
|
||||
u8 descriptor_type = usbd_otg->control_setup.wValue >> 8;
|
||||
u8 descriptor_subtype = usbd_otg->control_setup.wValue & 0xFF;
|
||||
@@ -931,7 +963,7 @@ static void _usbd_handle_get_descriptor(bool *transmit_data, void **descriptor,
|
||||
usb_device_descriptor.bcdDevice = (soc_rev >> 16) & 0xF; // MINORREV.
|
||||
usb_device_descriptor.bcdDevice |= ((soc_rev >> 4) & 0xF) << 8; // MAJORREV.
|
||||
*/
|
||||
*descriptor = usbd_otg->desc->dev;
|
||||
*desc = usbd_otg->desc->dev;
|
||||
*size = usbd_otg->desc->dev->bLength;
|
||||
*transmit_data = true;
|
||||
return;
|
||||
@@ -941,13 +973,13 @@ static void _usbd_handle_get_descriptor(bool *transmit_data, void **descriptor,
|
||||
{
|
||||
if (usbd_otg->port_speed == USB_HIGH_SPEED) // High speed. 512 bytes.
|
||||
{
|
||||
usbd_otg->desc->cfg->endpoint[0].wMaxPacketSize = 0x200;
|
||||
usbd_otg->desc->cfg->endpoint[1].wMaxPacketSize = 0x200;
|
||||
for (u32 i = 0; i < usbd_otg->desc->cfg->interface.bNumEndpoints; i++)
|
||||
usbd_otg->desc->cfg->endpoint[i].wMaxPacketSize = 0x200; // No burst.
|
||||
}
|
||||
else // Full speed. 64 bytes.
|
||||
{
|
||||
usbd_otg->desc->cfg->endpoint[0].wMaxPacketSize = 0x40;
|
||||
usbd_otg->desc->cfg->endpoint[1].wMaxPacketSize = 0x40;
|
||||
for (u32 i = 0; i < usbd_otg->desc->cfg->interface.bNumEndpoints; i++)
|
||||
usbd_otg->desc->cfg->endpoint[i].wMaxPacketSize = 0x40;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -955,20 +987,22 @@ static void _usbd_handle_get_descriptor(bool *transmit_data, void **descriptor,
|
||||
usb_cfg_hid_descr_t *tmp = (usb_cfg_hid_descr_t *)usbd_otg->desc->cfg;
|
||||
if (usbd_otg->port_speed == USB_HIGH_SPEED) // High speed. 512 bytes.
|
||||
{
|
||||
tmp->endpoint[0].wMaxPacketSize = 0x200;
|
||||
tmp->endpoint[1].wMaxPacketSize = 0x200;
|
||||
tmp->endpoint[0].bInterval = usbd_otg->gadget == USB_GADGET_HID_GAMEPAD ? 4 : 3; // 8ms : 4ms.
|
||||
tmp->endpoint[1].bInterval = usbd_otg->gadget == USB_GADGET_HID_GAMEPAD ? 4 : 3; // 8ms : 4ms.
|
||||
for (u32 i = 0; i < tmp->interface.bNumEndpoints; i++)
|
||||
{
|
||||
tmp->endpoint[i].wMaxPacketSize = 0x200;
|
||||
tmp->endpoint[i].bInterval = usbd_otg->gadget == USB_GADGET_HID_GAMEPAD ? 4 : 3; // 8ms : 4ms.
|
||||
}
|
||||
}
|
||||
else // Full speed. 64 bytes.
|
||||
{
|
||||
tmp->endpoint[0].wMaxPacketSize = 0x40;
|
||||
tmp->endpoint[1].wMaxPacketSize = 0x40;
|
||||
tmp->endpoint[0].bInterval = usbd_otg->gadget == USB_GADGET_HID_GAMEPAD ? 8 : 4; // 8ms : 4ms.
|
||||
tmp->endpoint[1].bInterval = usbd_otg->gadget == USB_GADGET_HID_GAMEPAD ? 8 : 4; // 8ms : 4ms.
|
||||
for (u32 i = 0; i < tmp->interface.bNumEndpoints; i++)
|
||||
{
|
||||
tmp->endpoint[i].wMaxPacketSize = 0x40;
|
||||
tmp->endpoint[i].bInterval = usbd_otg->gadget == USB_GADGET_HID_GAMEPAD ? 8 : 4; // 8ms : 4ms.
|
||||
}
|
||||
}
|
||||
}
|
||||
*descriptor = usbd_otg->desc->cfg;
|
||||
*desc = usbd_otg->desc->cfg;
|
||||
*size = usbd_otg->desc->cfg->config.wTotalLength;
|
||||
*transmit_data = true;
|
||||
return;
|
||||
@@ -976,23 +1010,23 @@ static void _usbd_handle_get_descriptor(bool *transmit_data, void **descriptor,
|
||||
switch (descriptor_subtype)
|
||||
{
|
||||
case 1:
|
||||
*descriptor = usbd_otg->desc->vendor;
|
||||
*desc = usbd_otg->desc->vendor;
|
||||
*size = usbd_otg->desc->vendor[0];
|
||||
break;
|
||||
case 2:
|
||||
*descriptor = usbd_otg->desc->product;
|
||||
*desc = usbd_otg->desc->product;
|
||||
*size = usbd_otg->desc->product[0];
|
||||
break;
|
||||
case 3:
|
||||
*descriptor = usbd_otg->desc->serial;
|
||||
*desc = usbd_otg->desc->serial;
|
||||
*size = usbd_otg->desc->serial[0];
|
||||
break;
|
||||
case 0xEE:
|
||||
*descriptor = usbd_otg->desc->ms_os;
|
||||
*desc = usbd_otg->desc->ms_os;
|
||||
*size = usbd_otg->desc->ms_os->bLength;
|
||||
break;
|
||||
default:
|
||||
*descriptor = usbd_otg->desc->lang_id;
|
||||
*desc = usbd_otg->desc->lang_id;
|
||||
*size = 4;
|
||||
break;
|
||||
}
|
||||
@@ -1002,7 +1036,7 @@ static void _usbd_handle_get_descriptor(bool *transmit_data, void **descriptor,
|
||||
if (!usbd_otg->desc->dev_qual)
|
||||
goto exit;
|
||||
usbd_otg->desc->dev_qual->bNumOtherConfigs = 1;
|
||||
*descriptor = usbd_otg->desc->dev_qual;
|
||||
*desc = usbd_otg->desc->dev_qual;
|
||||
*size = usbd_otg->desc->dev_qual->bLength;
|
||||
*transmit_data = true;
|
||||
return;
|
||||
@@ -1011,22 +1045,22 @@ static void _usbd_handle_get_descriptor(bool *transmit_data, void **descriptor,
|
||||
goto exit;
|
||||
if (usbd_otg->port_speed == USB_HIGH_SPEED)
|
||||
{
|
||||
usbd_otg->desc->cfg_other->endpoint[0].wMaxPacketSize = 0x40;
|
||||
usbd_otg->desc->cfg_other->endpoint[1].wMaxPacketSize = 0x40;
|
||||
for (u32 i = 0; i < usbd_otg->desc->cfg_other->interface.bNumEndpoints; i++)
|
||||
usbd_otg->desc->cfg_other->endpoint[i].wMaxPacketSize = 0x40;
|
||||
}
|
||||
else
|
||||
{
|
||||
usbd_otg->desc->cfg_other->endpoint[0].wMaxPacketSize = 0x200;
|
||||
usbd_otg->desc->cfg_other->endpoint[1].wMaxPacketSize = 0x200;
|
||||
for (u32 i = 0; i < usbd_otg->desc->cfg_other->interface.bNumEndpoints; i++)
|
||||
usbd_otg->desc->cfg_other->endpoint[i].wMaxPacketSize = 0x200;
|
||||
}
|
||||
if ((usbd_otg->charger_detect & 1) && (usbd_otg->charger_detect & 2))
|
||||
usbd_otg->desc->cfg_other->config.bMaxPower = 500 / 2;
|
||||
*descriptor = usbd_otg->desc->cfg_other;
|
||||
*desc = usbd_otg->desc->cfg_other;
|
||||
*size = usbd_otg->desc->cfg_other->config.wTotalLength;
|
||||
*transmit_data = true;
|
||||
return;
|
||||
case USB_DESCRIPTOR_DEVICE_BINARY_OBJECT:
|
||||
*descriptor = usbd_otg->desc->dev_bot;
|
||||
*desc = usbd_otg->desc->dev_bot;
|
||||
*size = usbd_otg->desc->dev_bot->wTotalLength;
|
||||
*transmit_data = true;
|
||||
return;
|
||||
@@ -1086,7 +1120,7 @@ static int _usbd_handle_ep0_control_transfer()
|
||||
bool ep_stall = false;
|
||||
bool transmit_data = false;
|
||||
|
||||
u8 *descriptor = (u8 *)USB_DESCRIPTOR_ADDR;
|
||||
u8 *desc = (u8 *)USB_DESCRIPTOR_ADDR;
|
||||
int size = 0;
|
||||
|
||||
u8 _bmRequestType = usbd_otg->control_setup.bmRequestType;
|
||||
@@ -1099,17 +1133,17 @@ static int _usbd_handle_ep0_control_transfer()
|
||||
|
||||
switch (_bmRequestType)
|
||||
{
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE):
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE): // 0x00.
|
||||
res = _usbd_handle_set_request(&ep_stall);
|
||||
break;
|
||||
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE):
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE): // 0x01.
|
||||
res = _usbd_ep_ack(USB_EP_CTRL_IN);
|
||||
if (!res)
|
||||
usbd_otg->interface_num = _wValue;
|
||||
break;
|
||||
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT):
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT): // 0x02.
|
||||
switch (_bRequest)
|
||||
{
|
||||
case USB_REQUEST_CLEAR_FEATURE:
|
||||
@@ -1153,25 +1187,25 @@ static int _usbd_handle_ep0_control_transfer()
|
||||
}
|
||||
break;
|
||||
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE):
|
||||
memset(descriptor, 0, _wLength);
|
||||
_usbd_handle_get_class_request(&transmit_data, descriptor, &size, &ep_stall);
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE): // 0x21.
|
||||
memset(desc, 0, _wLength);
|
||||
_usbd_handle_get_class_request(&transmit_data, desc, &size, &ep_stall);
|
||||
break;
|
||||
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE): // 0x80.
|
||||
switch (_bRequest)
|
||||
{
|
||||
case USB_REQUEST_GET_STATUS:
|
||||
descriptor[0] = USB_STATUS_DEV_SELF_POWERED;
|
||||
descriptor[1] = 0; // No support for remove wake up.
|
||||
desc[0] = USB_STATUS_DEV_SELF_POWERED;
|
||||
desc[1] = 0; // No support for remove wake up.
|
||||
transmit_data = true;
|
||||
size = 2;
|
||||
break;
|
||||
case USB_REQUEST_GET_DESCRIPTOR:
|
||||
_usbd_handle_get_descriptor(&transmit_data, (void **)&descriptor, &size, &ep_stall);
|
||||
_usbd_handle_get_descriptor(&transmit_data, (void **)&desc, &size, &ep_stall);
|
||||
break;
|
||||
case USB_REQUEST_GET_CONFIGURATION:
|
||||
descriptor = (u8 *)&usbd_otg->config_num;
|
||||
desc = (u8 *)&usbd_otg->config_num;
|
||||
size = _wLength;
|
||||
transmit_data = true;
|
||||
break;
|
||||
@@ -1181,28 +1215,28 @@ static int _usbd_handle_ep0_control_transfer()
|
||||
}
|
||||
break;
|
||||
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE): // 0x81.
|
||||
if (_bRequest == USB_REQUEST_GET_INTERFACE)
|
||||
{
|
||||
memset(descriptor, 0, _wLength);
|
||||
descriptor[0] = usbd_otg->interface_num;
|
||||
memset(desc, 0, _wLength);
|
||||
desc[0] = usbd_otg->interface_num;
|
||||
size = _wLength;
|
||||
}
|
||||
else if (_bRequest == USB_REQUEST_GET_STATUS)
|
||||
{
|
||||
memset(descriptor, 0, _wLength);
|
||||
memset(desc, 0, _wLength);
|
||||
size = _wLength;
|
||||
}
|
||||
else if (_bRequest == USB_REQUEST_GET_DESCRIPTOR && (_wValue >> 8) == USB_DESCRIPTOR_HID_REPORT && usbd_otg->gadget > USB_GADGET_UMS)
|
||||
else if (_bRequest == USB_REQUEST_GET_DESCRIPTOR && (_wValue >> 8) == USB_DESCRIPTOR_HID_REPORT && usbd_otg->gadget >= USB_GADGET_HID_GAMEPAD)
|
||||
{
|
||||
if (usbd_otg->gadget == USB_GADGET_HID_GAMEPAD)
|
||||
{
|
||||
descriptor = (u8 *)&hid_report_descriptor_jc;
|
||||
desc = (u8 *)&hid_report_descriptor_jc;
|
||||
size = hid_report_descriptor_jc_size;
|
||||
}
|
||||
else // USB_GADGET_HID_TOUCHPAD
|
||||
{
|
||||
descriptor = (u8 *)&hid_report_descriptor_touch;
|
||||
desc = (u8 *)&hid_report_descriptor_touch;
|
||||
size = hid_report_descriptor_touch_size;
|
||||
}
|
||||
|
||||
@@ -1219,7 +1253,7 @@ static int _usbd_handle_ep0_control_transfer()
|
||||
transmit_data = true;
|
||||
break;
|
||||
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT): // 0x82.
|
||||
if (_bRequest == USB_REQUEST_GET_STATUS)
|
||||
{
|
||||
int ep_req;
|
||||
@@ -1243,12 +1277,12 @@ static int _usbd_handle_ep0_control_transfer()
|
||||
}
|
||||
|
||||
size = _wLength;
|
||||
memset(descriptor, 0, size);
|
||||
memset(desc, 0, size);
|
||||
|
||||
if (_usbd_get_ep_status(ep_req) == USB_EP_STATUS_STALLED)
|
||||
descriptor[0] = USB_STATUS_EP_HALTED;
|
||||
desc[0] = USB_STATUS_EP_HALTED;
|
||||
else
|
||||
descriptor[0] = USB_STATUS_EP_OK;
|
||||
desc[0] = USB_STATUS_EP_OK;
|
||||
|
||||
transmit_data = true;
|
||||
}
|
||||
@@ -1256,24 +1290,24 @@ static int _usbd_handle_ep0_control_transfer()
|
||||
_usbd_stall_reset_ep1(3, USB_EP_CFG_STALL);
|
||||
break;
|
||||
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE):
|
||||
memset(descriptor, 0, _wLength);
|
||||
_usbd_handle_get_class_request(&transmit_data, descriptor, &size, &ep_stall);
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE): // 0xA1.
|
||||
memset(desc, 0, _wLength);
|
||||
_usbd_handle_get_class_request(&transmit_data, desc, &size, &ep_stall);
|
||||
break;
|
||||
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_INTERFACE):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_DEVICE):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_DEVICE): // 0xC0.
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_INTERFACE): // 0xC1.
|
||||
if (_bRequest == USB_REQUEST_GET_MS_DESCRIPTOR)
|
||||
{
|
||||
switch (_wIndex)
|
||||
{
|
||||
case USB_DESCRIPTOR_MS_COMPAT_ID:
|
||||
descriptor = (u8 *)usbd_otg->desc->ms_cid;
|
||||
desc = (u8 *)usbd_otg->desc->ms_cid;
|
||||
size = usbd_otg->desc->ms_cid->dLength;
|
||||
transmit_data = true;
|
||||
break;
|
||||
case USB_DESCRIPTOR_MS_EXTENDED_PROPERTIES:
|
||||
descriptor = (u8 *)usbd_otg->desc->mx_ext;
|
||||
desc = (u8 *)usbd_otg->desc->mx_ext;
|
||||
size = usbd_otg->desc->mx_ext->dLength;
|
||||
transmit_data = true;
|
||||
break;
|
||||
@@ -1294,7 +1328,7 @@ static int _usbd_handle_ep0_control_transfer()
|
||||
// Transmit data to HOST if any.
|
||||
if (transmit_data)
|
||||
{
|
||||
memcpy(usb_ep0_ctrl_buf, descriptor, size);
|
||||
memcpy(usb_ep0_ctrl_buf, desc, size);
|
||||
|
||||
if (_wLength < size)
|
||||
size = _wLength;
|
||||
@@ -1393,7 +1427,7 @@ int usb_device_enumerate(usb_gadget_type gadget)
|
||||
return _usbd_ep0_initialize();
|
||||
}
|
||||
|
||||
int usbd_handle_ep0_ctrl_setup()
|
||||
int usbd_handle_ep0_ctrl_setup(u32 *data)
|
||||
{
|
||||
// Acknowledge setup request for EP0 and copy its configuration.
|
||||
u32 ep0_setup_req = usbd_otg->regs->endptsetupstat;
|
||||
@@ -1405,6 +1439,15 @@ int usbd_handle_ep0_ctrl_setup()
|
||||
memset(usb_ep0_ctrl_buf, 0, USB_TD_BUFFER_PAGE_SIZE);
|
||||
}
|
||||
|
||||
if (usbd_otg->intr_idle_req)
|
||||
{
|
||||
if (data)
|
||||
*data = usbd_otg->intr_idle_rate;
|
||||
|
||||
usbd_otg->intr_idle_req = false;
|
||||
return USB_RES_OK;
|
||||
}
|
||||
|
||||
// Only return error if bulk reset was requested.
|
||||
if (usbd_otg->bulk_reset_req)
|
||||
{
|
||||
@@ -1487,7 +1530,7 @@ int usb_device_ep1_out_reading_finish(u32 *pending_bytes, u32 sync_timeout)
|
||||
if ((ep_status == USB_EP_STATUS_IDLE) || (ep_status == USB_EP_STATUS_DISABLED))
|
||||
break;
|
||||
|
||||
usbd_handle_ep0_ctrl_setup();
|
||||
usbd_handle_ep0_ctrl_setup(NULL);
|
||||
}
|
||||
while ((ep_status == USB_EP_STATUS_ACTIVE) || (ep_status == USB_EP_STATUS_STALLED));
|
||||
|
||||
@@ -1536,7 +1579,7 @@ int usb_device_ep1_in_writing_finish(u32 *pending_bytes, u32 sync_timeout)
|
||||
if ((ep_status == USB_EP_STATUS_IDLE) || (ep_status == USB_EP_STATUS_DISABLED))
|
||||
break;
|
||||
|
||||
usbd_handle_ep0_ctrl_setup();
|
||||
usbd_handle_ep0_ctrl_setup(NULL);
|
||||
}
|
||||
while ((ep_status == USB_EP_STATUS_ACTIVE) || (ep_status == USB_EP_STATUS_STALLED));
|
||||
|
||||
@@ -1572,7 +1615,7 @@ int usb_device_class_send_max_lun(u8 max_lun)
|
||||
|
||||
while (!usbd_otg->max_lun_set)
|
||||
{
|
||||
usbd_handle_ep0_ctrl_setup();
|
||||
usbd_handle_ep0_ctrl_setup(NULL);
|
||||
if (timer < get_tmr_ms() || btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
|
||||
return USB_ERROR_USER_ABORT;
|
||||
}
|
||||
@@ -1580,15 +1623,19 @@ int usb_device_class_send_max_lun(u8 max_lun)
|
||||
return USB_RES_OK;
|
||||
}
|
||||
|
||||
int usb_device_class_send_hid_report()
|
||||
int usb_device_class_send_hid_report(void *rpt_buffer, u32 rpt_size)
|
||||
{
|
||||
// Set buffers.
|
||||
usbd_otg->hid_rpt_buffer = rpt_buffer;
|
||||
usbd_otg->hid_rpt_size = rpt_size;
|
||||
|
||||
// Timeout if get GET_HID_REPORT request doesn't happen in 10s.
|
||||
u32 timer = get_tmr_ms() + 10000;
|
||||
|
||||
// Wait for request and transfer start.
|
||||
while (!usbd_otg->hid_report_sent)
|
||||
{
|
||||
usbd_handle_ep0_ctrl_setup();
|
||||
usbd_handle_ep0_ctrl_setup(NULL);
|
||||
if (timer < get_tmr_ms() || btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
|
||||
return USB_ERROR_USER_ABORT;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Enhanced & eXtensible USB Device (EDCI & XDCI) driver for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2019-2021 CTCaer
|
||||
* Copyright (c) 2019-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -31,11 +31,11 @@
|
||||
#define USB_EP_BUFFER_ALIGN (USB_TD_BUFFER_PAGE_SIZE)
|
||||
|
||||
#define USB_XFER_START 0
|
||||
#define USB_XFER_SYNCED_ENUM 1000000
|
||||
#define USB_XFER_SYNCED_CMD 1000000
|
||||
#define USB_XFER_SYNCED_DATA 2000000
|
||||
#define USB_XFER_SYNCED_CLASS 5000000
|
||||
#define USB_XFER_SYNCED -1
|
||||
#define USB_XFER_SYNCED_ENUM 1000000 // ~2s.
|
||||
#define USB_XFER_SYNCED_CMD 1000000 // ~2s.
|
||||
#define USB_XFER_SYNCED_DATA 2000000 // ~4s.
|
||||
#define USB_XFER_SYNCED_CLASS 5000000 // ~10s.
|
||||
#define USB_XFER_SYNCED -1 // Max.
|
||||
|
||||
typedef enum _usb_hid_type
|
||||
{
|
||||
@@ -122,6 +122,9 @@ typedef enum {
|
||||
|
||||
USB_REQUEST_GET_MS_DESCRIPTOR = 0x99,
|
||||
|
||||
USB_REQUEST_INTR_GET_REPORT = 1,
|
||||
USB_REQUEST_INTR_SET_IDLE = 10,
|
||||
|
||||
USB_REQUEST_BULK_GET_MAX_LUN = 0xFE,
|
||||
USB_REQUEST_BULK_RESET = 0xFF
|
||||
} usb_standard_req_t;
|
||||
@@ -167,12 +170,13 @@ typedef struct _usb_ops_t
|
||||
{
|
||||
int (*usbd_flush_endpoint)(u32);
|
||||
int (*usbd_set_ep_stall)(u32, int);
|
||||
int (*usbd_handle_ep0_ctrl_setup)();
|
||||
int (*usbd_handle_ep0_ctrl_setup)(u32 *);
|
||||
void (*usbd_end)(bool, bool);
|
||||
int (*usb_device_init)();
|
||||
int (*usb_device_enumerate)(usb_gadget_type gadget);
|
||||
int (*usb_device_enumerate)(usb_gadget_type);
|
||||
|
||||
int (*usb_device_class_send_max_lun)(u8);
|
||||
int (*usb_device_class_send_hid_report)();
|
||||
int (*usb_device_class_send_hid_report)(void *, u32);
|
||||
|
||||
int (*usb_device_ep1_out_read)(u8 *, u32, u32 *, u32);
|
||||
int (*usb_device_ep1_out_read_big)(u8 *, u32, u32 *);
|
||||
@@ -186,10 +190,17 @@ typedef struct _usb_ops_t
|
||||
typedef struct _usb_ctxt_t
|
||||
{
|
||||
u32 type;
|
||||
|
||||
// UMS.
|
||||
u32 partition;
|
||||
u32 offset;
|
||||
u32 sectors;
|
||||
u32 ro;
|
||||
|
||||
// HID.
|
||||
u32 idle;
|
||||
|
||||
// System.
|
||||
void (*system_maintenance)(bool);
|
||||
void *label;
|
||||
void (*set_text)(void *, const char *);
|
||||
@@ -201,4 +212,4 @@ void xusb_device_get_ops(usb_ops_t *ops);
|
||||
int usb_device_gadget_ums(usb_ctxt_t *usbs);
|
||||
int usb_device_gadget_hid(usb_ctxt_t *usbs);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
133
bdk/usb/xusbd.c
133
bdk/usb/xusbd.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* eXtensible USB Device driver (XDCI) for Tegra X1
|
||||
*
|
||||
* Copyright (c) 2020-2024 CTCaer
|
||||
* Copyright (c) 2020-2025 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -381,6 +381,10 @@ typedef struct _xusbd_controller_t
|
||||
|
||||
u8 max_lun;
|
||||
bool max_lun_set;
|
||||
void *hid_rpt_buffer;
|
||||
u32 hid_rpt_size;
|
||||
u32 intr_idle_rate;
|
||||
bool intr_idle_req;
|
||||
bool bulk_reset_req;
|
||||
} xusbd_controller_t;
|
||||
|
||||
@@ -1469,20 +1473,39 @@ static int _xusb_handle_get_class_request(const usb_ctrl_setup_t *ctrl_setup)
|
||||
u16 _wLength = ctrl_setup->wLength;
|
||||
|
||||
bool valid_interface = _wIndex == usbd_xotg->interface_num;
|
||||
bool valid_len = (_bRequest == USB_REQUEST_BULK_GET_MAX_LUN) ? 1 : 0;
|
||||
bool valid_val = (_bRequest >= USB_REQUEST_BULK_GET_MAX_LUN) ? (!_wValue) : true;
|
||||
|
||||
if (!valid_interface || _wValue != 0 || _wLength != valid_len)
|
||||
if (!valid_interface || !valid_val)
|
||||
goto stall;
|
||||
|
||||
switch (_bRequest)
|
||||
{
|
||||
case USB_REQUEST_INTR_GET_REPORT:
|
||||
if (usbd_xotg->hid_rpt_size != _wLength)
|
||||
goto stall;
|
||||
|
||||
// _wValue unused as there's only one report type and id.
|
||||
return _xusb_issue_data_trb(usbd_xotg->hid_rpt_buffer, usbd_xotg->hid_rpt_size, USB_DIR_IN);
|
||||
|
||||
case USB_REQUEST_INTR_SET_IDLE:
|
||||
if (_wLength)
|
||||
goto stall;
|
||||
|
||||
usbd_xotg->intr_idle_rate = (_wValue & 0xFF) * 4 * 1000; // Only one interface so upper byte ignored.
|
||||
usbd_xotg->intr_idle_req = true;
|
||||
return _xusb_issue_status_trb(USB_DIR_IN); // DELAYED_STATUS;
|
||||
|
||||
case USB_REQUEST_BULK_RESET:
|
||||
if (_wLength)
|
||||
goto stall;
|
||||
|
||||
usbd_xotg->bulk_reset_req = true;
|
||||
return _xusb_issue_status_trb(USB_DIR_IN); // DELAYED_STATUS;
|
||||
|
||||
case USB_REQUEST_BULK_GET_MAX_LUN:
|
||||
if (!usbd_xotg->max_lun_set)
|
||||
if (_wLength != 1 || !usbd_xotg->max_lun_set)
|
||||
goto stall;
|
||||
|
||||
usbd_xotg->device_state = XUSB_LUN_CONFIGURED_STS_WAIT;
|
||||
return _xusb_issue_data_trb(&usbd_xotg->max_lun, 1, USB_DIR_IN);
|
||||
}
|
||||
@@ -1495,7 +1518,7 @@ stall:
|
||||
static int _xusb_handle_get_descriptor(const usb_ctrl_setup_t *ctrl_setup)
|
||||
{
|
||||
u32 size;
|
||||
void *descriptor;
|
||||
void *desc;
|
||||
|
||||
u32 wLength = ctrl_setup->wLength;
|
||||
|
||||
@@ -1513,7 +1536,7 @@ static int _xusb_handle_get_descriptor(const usb_ctrl_setup_t *ctrl_setup)
|
||||
usb_device_descriptor.bcdDevice = (soc_rev >> 16) & 0xF; // MINORREV.
|
||||
usb_device_descriptor.bcdDevice |= ((soc_rev >> 4) & 0xF) << 8; // MAJORREV.
|
||||
*/
|
||||
descriptor = usbd_xotg->desc->dev;
|
||||
desc = usbd_xotg->desc->dev;
|
||||
size = usbd_xotg->desc->dev->bLength;
|
||||
break;
|
||||
case USB_DESCRIPTOR_CONFIGURATION:
|
||||
@@ -1522,13 +1545,13 @@ static int _xusb_handle_get_descriptor(const usb_ctrl_setup_t *ctrl_setup)
|
||||
{
|
||||
if (usbd_xotg->port_speed == XUSB_HIGH_SPEED) // High speed. 512 bytes.
|
||||
{
|
||||
usbd_xotg->desc->cfg->endpoint[0].wMaxPacketSize = 0x200; // No burst.
|
||||
usbd_xotg->desc->cfg->endpoint[1].wMaxPacketSize = 0x200; // No burst.
|
||||
for (u32 i = 0; i < usbd_xotg->desc->cfg->interface.bNumEndpoints; i++)
|
||||
usbd_xotg->desc->cfg->endpoint[i].wMaxPacketSize = 0x200; // No burst.
|
||||
}
|
||||
else // Full speed. 64 bytes.
|
||||
{
|
||||
usbd_xotg->desc->cfg->endpoint[0].wMaxPacketSize = 0x40;
|
||||
usbd_xotg->desc->cfg->endpoint[1].wMaxPacketSize = 0x40;
|
||||
for (u32 i = 0; i < usbd_xotg->desc->cfg->interface.bNumEndpoints; i++)
|
||||
usbd_xotg->desc->cfg->endpoint[i].wMaxPacketSize = 0x40;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1536,43 +1559,45 @@ static int _xusb_handle_get_descriptor(const usb_ctrl_setup_t *ctrl_setup)
|
||||
usb_cfg_hid_descr_t *tmp = (usb_cfg_hid_descr_t *)usbd_xotg->desc->cfg;
|
||||
if (usbd_xotg->port_speed == XUSB_HIGH_SPEED) // High speed. 512 bytes.
|
||||
{
|
||||
tmp->endpoint[0].wMaxPacketSize = 0x200;
|
||||
tmp->endpoint[1].wMaxPacketSize = 0x200;
|
||||
tmp->endpoint[0].bInterval = usbd_xotg->gadget == USB_GADGET_HID_GAMEPAD ? 4 : 3; // 8ms : 4ms.
|
||||
tmp->endpoint[1].bInterval = usbd_xotg->gadget == USB_GADGET_HID_GAMEPAD ? 4 : 3; // 8ms : 4ms.
|
||||
for (u32 i = 0; i < tmp->interface.bNumEndpoints; i++)
|
||||
{
|
||||
tmp->endpoint[i].wMaxPacketSize = 0x200;
|
||||
tmp->endpoint[i].bInterval = usbd_xotg->gadget == USB_GADGET_HID_GAMEPAD ? 4 : 3; // 8ms : 4ms.
|
||||
}
|
||||
}
|
||||
else // Full speed. 64 bytes.
|
||||
{
|
||||
tmp->endpoint[0].wMaxPacketSize = 0x40;
|
||||
tmp->endpoint[1].wMaxPacketSize = 0x40;
|
||||
tmp->endpoint[0].bInterval = usbd_xotg->gadget == USB_GADGET_HID_GAMEPAD ? 8 : 4; // 8ms : 4ms.
|
||||
tmp->endpoint[1].bInterval = usbd_xotg->gadget == USB_GADGET_HID_GAMEPAD ? 8 : 4; // 8ms : 4ms.
|
||||
for (u32 i = 0; i < tmp->interface.bNumEndpoints; i++)
|
||||
{
|
||||
tmp->endpoint[i].wMaxPacketSize = 0x40;
|
||||
tmp->endpoint[i].bInterval = usbd_xotg->gadget == USB_GADGET_HID_GAMEPAD ? 8 : 4; // 8ms : 4ms.
|
||||
}
|
||||
}
|
||||
}
|
||||
descriptor = usbd_xotg->desc->cfg;
|
||||
desc = usbd_xotg->desc->cfg;
|
||||
size = usbd_xotg->desc->cfg->config.wTotalLength;
|
||||
break;
|
||||
case USB_DESCRIPTOR_STRING:
|
||||
switch (descriptor_subtype)
|
||||
{
|
||||
case 1:
|
||||
descriptor = usbd_xotg->desc->vendor;
|
||||
desc = usbd_xotg->desc->vendor;
|
||||
size = usbd_xotg->desc->vendor[0];
|
||||
break;
|
||||
case 2:
|
||||
descriptor = usbd_xotg->desc->product;
|
||||
desc = usbd_xotg->desc->product;
|
||||
size = usbd_xotg->desc->product[0];
|
||||
break;
|
||||
case 3:
|
||||
descriptor = usbd_xotg->desc->serial;
|
||||
desc = usbd_xotg->desc->serial;
|
||||
size = usbd_xotg->desc->serial[0];
|
||||
break;
|
||||
case 0xEE:
|
||||
descriptor = usbd_xotg->desc->ms_os;
|
||||
desc = usbd_xotg->desc->ms_os;
|
||||
size = usbd_xotg->desc->ms_os->bLength;
|
||||
break;
|
||||
default:
|
||||
descriptor = usbd_xotg->desc->lang_id;
|
||||
desc = usbd_xotg->desc->lang_id;
|
||||
size = 4;
|
||||
break;
|
||||
}
|
||||
@@ -1584,7 +1609,7 @@ static int _xusb_handle_get_descriptor(const usb_ctrl_setup_t *ctrl_setup)
|
||||
return USB_RES_OK;
|
||||
}
|
||||
usbd_xotg->desc->dev_qual->bNumOtherConfigs = 0;
|
||||
descriptor = usbd_xotg->desc->dev_qual;
|
||||
desc = usbd_xotg->desc->dev_qual;
|
||||
size = usbd_xotg->desc->dev_qual->bLength;
|
||||
break;
|
||||
case USB_DESCRIPTOR_OTHER_SPEED_CONFIGURATION:
|
||||
@@ -1595,19 +1620,19 @@ static int _xusb_handle_get_descriptor(const usb_ctrl_setup_t *ctrl_setup)
|
||||
}
|
||||
if (usbd_xotg->port_speed == XUSB_HIGH_SPEED)
|
||||
{
|
||||
usbd_xotg->desc->cfg_other->endpoint[0].wMaxPacketSize = 0x40;
|
||||
usbd_xotg->desc->cfg_other->endpoint[1].wMaxPacketSize = 0x40;
|
||||
for (u32 i = 0; i < usbd_xotg->desc->cfg_other->interface.bNumEndpoints; i++)
|
||||
usbd_xotg->desc->cfg_other->endpoint[i].wMaxPacketSize = 0x40;
|
||||
}
|
||||
else
|
||||
{
|
||||
usbd_xotg->desc->cfg_other->endpoint[0].wMaxPacketSize = 0x200;
|
||||
usbd_xotg->desc->cfg_other->endpoint[1].wMaxPacketSize = 0x200;
|
||||
for (u32 i = 0; i < usbd_xotg->desc->cfg_other->interface.bNumEndpoints; i++)
|
||||
usbd_xotg->desc->cfg_other->endpoint[i].wMaxPacketSize = 0x200;
|
||||
}
|
||||
descriptor = usbd_xotg->desc->cfg_other;
|
||||
desc = usbd_xotg->desc->cfg_other;
|
||||
size = usbd_xotg->desc->cfg_other->config.wTotalLength;
|
||||
break;
|
||||
case USB_DESCRIPTOR_DEVICE_BINARY_OBJECT:
|
||||
descriptor = usbd_xotg->desc->dev_bot;
|
||||
desc = usbd_xotg->desc->dev_bot;
|
||||
size = usbd_xotg->desc->dev_bot->wTotalLength;
|
||||
break;
|
||||
default:
|
||||
@@ -1618,7 +1643,7 @@ static int _xusb_handle_get_descriptor(const usb_ctrl_setup_t *ctrl_setup)
|
||||
if (wLength < size)
|
||||
size = wLength;
|
||||
|
||||
return _xusb_issue_data_trb(descriptor, size, USB_DIR_IN);
|
||||
return _xusb_issue_data_trb(desc, size, USB_DIR_IN);
|
||||
}
|
||||
|
||||
static void _xusb_handle_set_request_dev_address(const usb_ctrl_setup_t *ctrl_setup)
|
||||
@@ -1688,18 +1713,18 @@ static int _xusbd_handle_ep0_control_transfer(usb_ctrl_setup_t *ctrl_setup)
|
||||
|
||||
switch (_bmRequestType)
|
||||
{
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE):
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE): // 0x00.
|
||||
if (_bRequest == USB_REQUEST_SET_ADDRESS)
|
||||
_xusb_handle_set_request_dev_address(ctrl_setup);
|
||||
else if (_bRequest == USB_REQUEST_SET_CONFIGURATION)
|
||||
_xusb_handle_set_request_configuration(ctrl_setup);
|
||||
return USB_RES_OK; // What about others.
|
||||
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE):
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE): // 0x01.
|
||||
usbd_xotg->interface_num = _wValue;
|
||||
return _xusb_issue_status_trb(USB_DIR_IN);
|
||||
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT):
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT): // 0x02.
|
||||
if ((_wValue & 0xFF) == USB_FEATURE_ENDPOINT_HALT)
|
||||
{
|
||||
if (_bRequest == USB_REQUEST_CLEAR_FEATURE || _bRequest == USB_REQUEST_SET_FEATURE)
|
||||
@@ -1735,10 +1760,10 @@ static int _xusbd_handle_ep0_control_transfer(usb_ctrl_setup_t *ctrl_setup)
|
||||
ep_stall = true;
|
||||
break;
|
||||
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE):
|
||||
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE): // 0x21.
|
||||
return _xusb_handle_get_class_request(ctrl_setup);
|
||||
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE): // 0x80.
|
||||
switch (_bRequest)
|
||||
{
|
||||
case USB_REQUEST_GET_STATUS:
|
||||
@@ -1760,7 +1785,7 @@ static int _xusbd_handle_ep0_control_transfer(usb_ctrl_setup_t *ctrl_setup)
|
||||
}
|
||||
break;
|
||||
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE): // 0x81.
|
||||
if (_bRequest == USB_REQUEST_GET_INTERFACE)
|
||||
{
|
||||
desc = xusb_interface_descriptor;
|
||||
@@ -1774,7 +1799,7 @@ static int _xusbd_handle_ep0_control_transfer(usb_ctrl_setup_t *ctrl_setup)
|
||||
size = sizeof(xusb_status_descriptor);
|
||||
transmit_data = true;
|
||||
}
|
||||
else if (_bRequest == USB_REQUEST_GET_DESCRIPTOR && (_wValue >> 8) == USB_DESCRIPTOR_HID_REPORT && usbd_xotg->gadget > USB_GADGET_UMS)
|
||||
else if (_bRequest == USB_REQUEST_GET_DESCRIPTOR && (_wValue >> 8) == USB_DESCRIPTOR_HID_REPORT && usbd_xotg->gadget >= USB_GADGET_HID_GAMEPAD)
|
||||
{
|
||||
if (usbd_xotg->gadget == USB_GADGET_HID_GAMEPAD)
|
||||
{
|
||||
@@ -1793,7 +1818,7 @@ static int _xusbd_handle_ep0_control_transfer(usb_ctrl_setup_t *ctrl_setup)
|
||||
ep_stall = true;
|
||||
break;
|
||||
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT): // 0x82.
|
||||
if (_bRequest == USB_REQUEST_GET_STATUS)
|
||||
{
|
||||
u32 ep = 0;
|
||||
@@ -1821,11 +1846,11 @@ static int _xusbd_handle_ep0_control_transfer(usb_ctrl_setup_t *ctrl_setup)
|
||||
ep_stall = true;
|
||||
break;
|
||||
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE): // 0xA1.
|
||||
return _xusb_handle_get_class_request(ctrl_setup);
|
||||
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_INTERFACE):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_DEVICE):
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_DEVICE): // 0xC0.
|
||||
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_INTERFACE): // 0xC1.
|
||||
if (_bRequest == USB_REQUEST_GET_MS_DESCRIPTOR)
|
||||
{
|
||||
switch (_wIndex)
|
||||
@@ -2017,12 +2042,24 @@ void xusb_end(bool reset_ep, bool only_controller)
|
||||
_xusb_device_power_down();
|
||||
}
|
||||
|
||||
int xusb_handle_ep0_ctrl_setup()
|
||||
int xusb_handle_ep0_ctrl_setup(u32 *data)
|
||||
{
|
||||
/*
|
||||
* EP0 Control handling is done by normal ep operation in XUSB.
|
||||
* Here we handle the bulk reset only.
|
||||
* Here we handle the interface only, except if HID.
|
||||
*/
|
||||
if (usbd_xotg->gadget >= USB_GADGET_HID_GAMEPAD)
|
||||
_xusb_ep_operation(1);
|
||||
|
||||
if (usbd_xotg->intr_idle_req)
|
||||
{
|
||||
if (data)
|
||||
*data = usbd_xotg->intr_idle_rate;
|
||||
|
||||
usbd_xotg->intr_idle_req = false;
|
||||
return USB_RES_OK;
|
||||
}
|
||||
|
||||
if (usbd_xotg->bulk_reset_req)
|
||||
{
|
||||
usbd_xotg->bulk_reset_req = false;
|
||||
@@ -2176,8 +2213,12 @@ bool xusb_device_class_send_max_lun(u8 max_lun)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool xusb_device_class_send_hid_report()
|
||||
bool xusb_device_class_send_hid_report(void *rpt_buffer, u32 rpt_size)
|
||||
{
|
||||
// Set buffers.
|
||||
usbd_xotg->hid_rpt_buffer = rpt_buffer;
|
||||
usbd_xotg->hid_rpt_size = rpt_size;
|
||||
|
||||
// Timeout if get GET_HID_REPORT request doesn't happen in 10s.
|
||||
u32 timer = get_tmr_ms() + 10000;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user