mirror of
https://github.com/IllusionMan1212/vitasdk-odin.git
synced 2026-10-24 02:12:38 +00:00
407 lines
12 KiB
Odin
407 lines
12 KiB
Odin
package udcd
|
|
|
|
import "core:c"
|
|
import sce "../common"
|
|
|
|
SceUdcdStatus :: enum c.int {
|
|
CONNECTION_NEW = 0x0001,
|
|
CONNECTION_ESTABLISHED = 0x0002,
|
|
CONNECTION_SUSPENDED = 0x0004,
|
|
CABLE_DISCONNECTED = 0x0010,
|
|
CABLE_CONNECTED = 0x0020,
|
|
DEACTIVATED = 0x0100,
|
|
ACTIVATED = 0x0200,
|
|
IS_CHARGING = 0x0400,
|
|
USE_USB_CHARGING = 0x0800,
|
|
UNKNOWN_1000 = 0x1000,
|
|
UNKNOWN_2000 = 0x2000
|
|
}
|
|
|
|
SceUdcdStatusDriver :: enum c.int {
|
|
STARTED = 0x01,
|
|
REGISTERED = 0x02,
|
|
}
|
|
|
|
SceUdcdDeviceInfo :: struct {
|
|
info: [64]c.uchar,
|
|
}
|
|
#assert(size_of(SceUdcdDeviceInfo) == 0x40)
|
|
|
|
SceUdcdWaitParam :: struct {
|
|
unk_00: c.int,
|
|
status: c.int,
|
|
unk_08: c.int,
|
|
unk_0C: c.int,
|
|
unk_10: c.int,
|
|
driverName: cstring,
|
|
}
|
|
|
|
SceUdcdDeviceState :: struct {
|
|
unk_00: c.int,
|
|
state: c.int,
|
|
cable: c.int,
|
|
connection: c.int,
|
|
use_usb_charging: c.int,
|
|
unk_14: c.int,
|
|
}
|
|
#assert(size_of(SceUdcdDeviceState) == 0x18)
|
|
|
|
|
|
/** Enumeration for Device and/or Interface Class codes
|
|
*/
|
|
SceUdcdUsbClass :: enum c.int {
|
|
PER_INTERFACE = 0x00, //!< for DeviceClass
|
|
AUDIO = 0x01,
|
|
COMM = 0x02,
|
|
HID = 0x03,
|
|
PTP = 0x06,
|
|
PRINTER = 0x07,
|
|
MASS_STORAGE = 0x08,
|
|
HUB = 0x09,
|
|
DATA = 0x0A,
|
|
VIDEO = 0x0E,
|
|
VENDOR_SPEC = 0xFF
|
|
}
|
|
|
|
/** Enumeration for descriptor types
|
|
*/
|
|
SceUdcdUsbDt :: enum c.int {
|
|
DEVICE = 0x01,
|
|
CONFIG = 0x02,
|
|
STRING = 0x03,
|
|
INTERFACE = 0x04,
|
|
ENDPOINT = 0x05
|
|
}
|
|
|
|
/** Enumeration for standard requests
|
|
*/
|
|
SceUdcdUsbReq :: enum c.int {
|
|
GET_STATUS = 0x00,
|
|
CLEAR_FEATURE = 0x01,
|
|
SET_FEATURE = 0x03,
|
|
SET_ADDRESS = 0x05,
|
|
GET_DESCRIPTOR = 0x06,
|
|
SET_DESCRIPTOR = 0x07,
|
|
GET_CONFIG = 0x08,
|
|
SET_CONFIG = 0x09,
|
|
GET_INTERFACE = 0x0A,
|
|
SET_INTERFACE = 0x0B,
|
|
SYNC_FRAME = 0x0C
|
|
}
|
|
|
|
/**
|
|
* Descriptor sizes per descriptor type
|
|
*/
|
|
USB_DT_DEVICE_SIZE :: 18
|
|
USB_DT_CONFIG_SIZE :: 9
|
|
USB_DT_INTERFACE_SIZE :: 9
|
|
USB_DT_ENDPOINT_SIZE :: 7
|
|
USB_DT_ENDPOINT_AUDIO_SIZE :: 9 //!< Audio extension
|
|
USB_DT_HUB_NONVAR_SIZE :: 7
|
|
|
|
/** Control message request type bitmask
|
|
*/
|
|
USB_CTRLTYPE_DIR_MASK :: 0x80
|
|
USB_CTRLTYPE_DIR_HOST2DEVICE :: (0 << 7)
|
|
USB_CTRLTYPE_DIR_DEVICE2HOST :: (1 << 7)
|
|
USB_CTRLTYPE_TYPE_MASK :: 0x60
|
|
USB_CTRLTYPE_TYPE_STANDARD :: (0 << 5)
|
|
USB_CTRLTYPE_TYPE_CLASS :: (1 << 5)
|
|
USB_CTRLTYPE_TYPE_VENDOR :: (2 << 5)
|
|
USB_CTRLTYPE_TYPE_RESERVED :: (3 << 5)
|
|
USB_CTRLTYPE_REC_MASK :: 0x1f
|
|
USB_CTRLTYPE_REC_DEVICE :: 0
|
|
USB_CTRLTYPE_REC_INTERFACE :: 1
|
|
USB_CTRLTYPE_REC_ENDPOINT :: 2
|
|
USB_CTRLTYPE_REC_OTHER :: 3
|
|
|
|
/** Endpoint types and masks
|
|
*/
|
|
USB_ENDPOINT_ADDRESS_MASK :: 0x0f /* in bEndpointAddress */
|
|
USB_ENDPOINT_DIR_MASK :: 0x80
|
|
|
|
USB_FEATURE_ENDPOINT_HALT :: 0
|
|
|
|
USB_ENDPOINT_IN :: 0x80
|
|
USB_ENDPOINT_OUT :: 0x00
|
|
|
|
USB_ENDPOINT_TYPE_MASK :: 0x03 /* in bmAttributes */
|
|
USB_ENDPOINT_TYPE_CONTROL :: 0
|
|
USB_ENDPOINT_TYPE_ISOCHRONOUS :: 1
|
|
USB_ENDPOINT_TYPE_BULK :: 2
|
|
USB_ENDPOINT_TYPE_INTERRUPT :: 3
|
|
|
|
/* HID constants. Not part of chapter 9 */
|
|
|
|
/** Class-Specific Requests
|
|
*/
|
|
SceUdcdHidRequest :: enum c.int {
|
|
GET_REPORT = 0x01,
|
|
GET_IDLE = 0x02,
|
|
GET_PROTOCOL = 0x03,
|
|
SET_REPORT = 0x09,
|
|
SET_IDLE = 0x0A,
|
|
SET_PROTOCOL = 0x0B
|
|
}
|
|
|
|
/** Class Descriptor Types
|
|
*/
|
|
SceUdcdHidDescriptor :: enum c.int {
|
|
HID = 0x21,
|
|
REPORT = 0x22,
|
|
PHY = 0x23
|
|
}
|
|
|
|
/** Protocol Selection
|
|
*/
|
|
SceUdcdProtocol :: enum c.int {
|
|
BOOT_PROTOCOL = 0x00,
|
|
RPT_PROTOCOL = 0x01
|
|
}
|
|
|
|
/** HID Interface Class Code
|
|
*/
|
|
HID_INTF :: 0x03
|
|
|
|
/** HID Interface Class SubClass Codes
|
|
*/
|
|
BOOT_INTF_SUBCLASS :: 0x01
|
|
|
|
/** HID Interface Class Protocol Codes
|
|
*/
|
|
SceUdcdHidProtocol :: enum c.int {
|
|
NONE = 0x00,
|
|
KEYBOARD = 0x01,
|
|
MOUSE = 0x02
|
|
}
|
|
|
|
/** USB limits
|
|
*/
|
|
SCE_UDCD_MAX_INTERFACES :: 8
|
|
SCE_UDCD_MAX_ENDPOINTS :: 9
|
|
SCE_UDCD_MAX_ALTERNATE :: 2
|
|
|
|
SceUdcdRetcode :: enum c.int {
|
|
CANCEL = -1,
|
|
CANCEL_ALL = -2,
|
|
CANCEL_TRANSMISSION = -3,
|
|
SUCCESS = 0,
|
|
SEND = 1,
|
|
RECV = 2
|
|
}
|
|
|
|
/** Error codes
|
|
*/
|
|
SceUdcdErrorCode :: enum c.uint {
|
|
ILLEGAL_CONTEXT = 0x80000030,
|
|
INVALID_POINTER = 0x80000103,
|
|
INVALID_FLAG = 0x80000105,
|
|
INVALID_VALUE = 0x800001FE,
|
|
ALREADY_DONE = 0x80243001,
|
|
INVALID_ARGUMENT = 0x80243002,
|
|
ARGUMENT_EXCEEDED_LIMIT = 0x80243003,
|
|
MEMORY_EXHAUSTED = 0x80243004,
|
|
DRIVER_NOT_FOUND = 0x80243005,
|
|
DRIVER_IN_PROGRESS = 0x80243006,
|
|
BUS_DRIVER_NOT_STARTED = 0x80243007,
|
|
WAIT_TIMEOUT = 0x80243008,
|
|
WAIT_CANCEL = 0x80243009,
|
|
USBDRIVER_INVALID_DRIVER = 0x80243200,
|
|
USBDRIVER_INVALID_NAME = 0x80243201,
|
|
USBDRIVER_INVALID_FUNCS = 0x80243202
|
|
}
|
|
|
|
/** SceUdcdDeviceRequest Flags
|
|
*/
|
|
SceUdcdDeviceRequestAttr :: enum c.int {
|
|
PHYCONT = 0x00000001
|
|
}
|
|
|
|
/** USB string descriptor
|
|
*/
|
|
SceUdcdStringDescriptor :: struct {
|
|
bLength: c.uchar,
|
|
bDescriptorType: c.uchar,
|
|
bString: [31]c.short,
|
|
}
|
|
#assert(size_of(SceUdcdStringDescriptor) == 0x40)
|
|
|
|
/** USB device descriptor
|
|
*/
|
|
SceUdcdDeviceDescriptor :: struct #align(4) {
|
|
bLength: c.uchar,
|
|
bDescriptorType: c.uchar,
|
|
bcdUSB: c.ushort,
|
|
bDeviceClass: c.uchar,
|
|
bDeviceSubClass: c.uchar,
|
|
bDeviceProtocol: c.uchar,
|
|
bMaxPacketSize0: c.uchar,
|
|
idVendor: c.ushort,
|
|
idProduct: c.ushort,
|
|
bcdDevice: c.ushort,
|
|
iManufacturer: c.uchar,
|
|
iProduct: c.uchar,
|
|
iSerialNumber: c.uchar,
|
|
bNumConfigurations: c.uchar,
|
|
}
|
|
#assert(size_of(SceUdcdDeviceDescriptor) == 0x14)
|
|
|
|
/** USB device qualifier descriptor
|
|
*/
|
|
SceUdcdDeviceQualifierDescriptor :: struct #align(4) {
|
|
bLength: c.uchar,
|
|
bDescriptorType: c.uchar,
|
|
bcdUSB: c.ushort,
|
|
bDeviceClass: c.uchar,
|
|
bDeviceSubClass: c.uchar,
|
|
bDeviceProtocol: c.uchar,
|
|
bMaxPacketSize0: c.uchar,
|
|
bNumConfigurations: c.uchar,
|
|
bReserved: c.uchar,
|
|
}
|
|
#assert(size_of(SceUdcdDeviceQualifierDescriptor) == 0xC)
|
|
|
|
/** USB configuration descriptor
|
|
*/
|
|
SceUdcdConfigDescriptor :: struct {
|
|
bLength: c.uchar,
|
|
bDescriptorType: c.uchar,
|
|
wTotalLength: c.ushort,
|
|
bNumInterfaces: c.uchar,
|
|
bConfigurationValue: c.uchar,
|
|
iConfiguration: c.uchar,
|
|
bmAttributes: c.uchar,
|
|
bMaxPower: c.uchar,
|
|
settings: ^SceUdcdInterfaceSettings,
|
|
extra: [^]c.char, //!< Extra descriptors
|
|
extraLength: c.int,
|
|
}
|
|
|
|
/** USB driver interfaces structure
|
|
*/
|
|
SceUdcdInterfaceSettings :: struct {
|
|
descriptors: [^]SceUdcdInterfaceDescriptor, //!< Pointers to the individual interface descriptors
|
|
alternateSetting: c.uint,
|
|
numDescriptors: c.uint, //!< Number of interface descriptors
|
|
}
|
|
|
|
/** USB Interface descriptor
|
|
*/
|
|
SceUdcdInterfaceDescriptor :: struct {
|
|
bLength: c.uchar,
|
|
bDescriptorType: c.uchar,
|
|
bInterfaceNumber: c.uchar,
|
|
bAlternateSetting: c.uchar,
|
|
bNumEndpoints: c.uchar,
|
|
bInterfaceClass: c.uchar,
|
|
bInterfaceSubClass: c.uchar,
|
|
bInterfaceProtocol: c.uchar,
|
|
iInterface: c.uchar,
|
|
endpoints: [^]SceUdcdEndpointDescriptor,
|
|
extra: [^]c.char, //!< Extra descriptors
|
|
extraLength: c.int,
|
|
}
|
|
|
|
/** USB endpoint descriptor
|
|
*/
|
|
SceUdcdEndpointDescriptor :: struct {
|
|
bLength: c.uchar,
|
|
bDescriptorType: c.uchar,
|
|
bEndpointAddress: c.uchar,
|
|
bmAttributes: c.uchar,
|
|
wMaxPacketSize: c.ushort,
|
|
bInterval: c.uchar,
|
|
extra: [^]c.char, //!< Extra descriptors
|
|
extraLength: c.int,
|
|
}
|
|
|
|
/** USB driver interface
|
|
*/
|
|
SceUdcdInterface :: struct {
|
|
expectNumber: c.int, //!< Expectant interface number (interface number or -1)
|
|
interfaceNumber: c.int, //!< End interface
|
|
numInterfaces: c.int, //!< Number of interfaces
|
|
}
|
|
#assert(size_of(SceUdcdInterface) == 0xC)
|
|
|
|
/** USB driver endpoint
|
|
*/
|
|
SceUdcdEndpoint :: struct {
|
|
direction: c.int, //!< USB_ENDPOINT_IN / USB_ENDPOINT_OUT
|
|
driverEndpointNumber: c.int, //!< Driver Endpoint number (must be filled in sequentially)
|
|
endpointNumber: c.int, //!< Endpoint number (Filled in by the bus driver)
|
|
transmittedBytes: c.int, //!< Number of transmitted bytes
|
|
}
|
|
#assert(size_of(SceUdcdEndpoint) == 0x10)
|
|
|
|
/** USB driver configuration
|
|
*/
|
|
SceUdcdConfiguration :: struct {
|
|
configDescriptors: ^SceUdcdConfigDescriptor, //!< Pointer to the configuration descriptors
|
|
settings: ^SceUdcdInterfaceSettings, //!< USB driver interface settings
|
|
interfaceDescriptors: ^SceUdcdInterfaceDescriptor, //!< Pointer to the first interface descriptor
|
|
endpointDescriptors: ^SceUdcdEndpointDescriptor, //!< Pointer to the first endpoint descriptor
|
|
}
|
|
|
|
/** USB EP0 Device Request
|
|
*/
|
|
SceUdcdEP0DeviceRequest :: struct {
|
|
bmRequestType: c.uchar,
|
|
bRequest: c.uchar,
|
|
wValue: c.ushort,
|
|
wIndex: c.ushort,
|
|
wLength: c.ushort,
|
|
}
|
|
#assert(size_of(SceUdcdEP0DeviceRequest) == 8)
|
|
|
|
/** USB driver structure
|
|
*/
|
|
SceUdcdDriver :: struct {
|
|
driverName: cstring, //!< Name of the USB driver
|
|
numEndpoints: c.int, //!< Number of endpoints in this driver (including default control)
|
|
endpoints: ^SceUdcdEndpoint, //!< List of endpoint structures (used when calling other functions)
|
|
interface: ^SceUdcdInterface, //!< Interface list
|
|
descriptor_hi: ^SceUdcdDeviceDescriptor, //!< Pointer to hi-speed device descriptor
|
|
configuration_hi: ^SceUdcdConfiguration, //!< Pointer to hi-speed device configuration
|
|
descriptor: ^SceUdcdDeviceDescriptor, //!< Pointer to full-speed device descriptor
|
|
configuration: ^SceUdcdConfiguration, //!< Pointer to full-speed device configuration
|
|
stringDescriptors: ^SceUdcdStringDescriptor, //!< Default string descriptors
|
|
stringDescriptorProduct: ^SceUdcdStringDescriptor, //!< Product string descriptor (iProduct has to be 2)
|
|
stringDescriptorSerial: ^SceUdcdStringDescriptor, //!< Serial string descriptor (iSerial has to be 3)
|
|
processRequest: #type ^proc "c" (recipient: c.int, arg: c.int, req: ^SceUdcdEP0DeviceRequest, user_data: rawptr) -> c.int,//!< Received a control request
|
|
changeSetting: #type ^proc "c" (interfaceNumber: c.int, alternateSetting: c.int, bus: c.int) -> c.int,//!< Change alternate setting
|
|
attach: #type ^proc "c" (usb_version: c.int, user_data: rawptr) -> c.int,//!< Configuration set (attach) function
|
|
detach: #type ^proc "c" (user_data: rawptr),//!< Configuration unset (detach) function
|
|
configure: #type ^proc "c" (usb_version: c.int, desc_count: c.int, settings: ^SceUdcdInterfaceSettings, user_data: rawptr), //!< Configure the device
|
|
start: #type ^proc "c" (size: c.int, args: rawptr, user_data: rawptr) -> c.int, //!< Function called when the driver is started
|
|
stop: #type ^proc "c" (size: c.int, args: rawptr, user_data: rawptr) -> c.int,//!< Function called when the driver is stopped
|
|
user_data: rawptr, //!< User data
|
|
bus: c.int, //!< USB bus
|
|
link: ^SceUdcdDriver, //!< Link to next USB driver in the chain, set to NULL
|
|
}
|
|
|
|
/** USB device request
|
|
*/
|
|
SceUdcdDeviceRequest :: struct {
|
|
endpoint: ^SceUdcdEndpoint, //!< Pointer to the endpoint to queue request on
|
|
data: rawptr, //!< Pointer to the data buffer to use in the request
|
|
attributes: c.uint, //!< Request attributes (See ::SceUdcdDeviceRequestAttr)
|
|
size: c.int, //!< Size of the data buffer
|
|
isControlRequest: c.int, //!< Is a control request?
|
|
onComplete: #type ^proc "c" (req: ^SceUdcdDeviceRequest), //!< Pointer to the function to call on completion
|
|
transmitted: c.int, //!< Number of transmitted bytes
|
|
returnCode: c.int, //!< Return code of the request (See ::SceUdcdRetcode)
|
|
next: ^SceUdcdDeviceRequest, //!< Link pointer to next request used by the driver, set it to NULL
|
|
unused: rawptr, //!< An unused value (maybe an argument)
|
|
physicalAddress: rawptr, //!< Physical address
|
|
}
|
|
|
|
/** USB driver name
|
|
*/
|
|
SceUdcdDriverName :: struct #align(16) {
|
|
size: c.int,
|
|
name: [32]c.char,
|
|
flags: c.int,
|
|
}
|
|
|