#
OBJ = main.o
-OBJ += usb.o usb_lowlevel.o usb_devinit.o usb_io.o usb_poll.o
+OBJ += usb.o usb_lowlevel.o usb_devinit.o usb_io.o usb_poll.o usb_info.o
OBJ += hub.o
CPPFLAGS = -Iinclude
NAME = Core
extern void USB_RegisterDriver(tUSBDriver *Driver);
+// --- Driver Pointer ---
extern void *USB_GetDeviceDataPtr(tUSBInterface *Dev);
extern void USB_SetDeviceDataPtr(tUSBInterface *Dev, void *Ptr);
+// --- Device/Interface information ---
+extern Uint32 USB_GetInterfaceClass(tUSBInterface *Dev);
+extern void USB_GetDeviceVendor(tUSBInterface *Dev, Uint16 *VendorID, Uint16 *DeviceID);
+extern char *USB_GetSerialNumber(tUSBInterface *Dev);
+
+// --- Device IO ---
extern void USB_StartPollingEndpoint(tUSBInterface *Dev, int Endpoint);
extern void USB_ReadDescriptor(tUSBInterface *Dev, int Type, int Index, int Length, void *Data);
extern void USB_Request(tUSBInterface *Dev, int Endpoint, int Type, int Req, int Value, int Index, int Len, void *Data);
// TODO: Async
extern void USB_SendData(tUSBInterface *Dev, int Endpoint, size_t Length, const void *Data);
extern void USB_RecvData(tUSBInterface *Dev, int Endpoint, size_t Length, void *Data);
-extern void USB_RecvDataA(tUSBInterface *Dev, int Endpoint, int Length, void *DataBuf, tUSB_DataCallback Callback);
+extern void USB_RecvDataA(tUSBInterface *Dev, int Endpoint, size_t Length, void *DataBuf, tUSB_DataCallback Callback);
#endif
#include <usb_core.h>
#include <usb_hub.h>
#include <usb_host.h>
+#include "usb_proto.h"
typedef struct sUSBHost tUSBHost;
typedef struct sUSBDevice tUSBDevice;
tUSBDriver *Driver;
void *Data;
+
+ struct sDescriptor_Interface IfaceDesc;
int nEndpoints;
tUSBEndpoint Endpoints[];
tUSBHost *Host;
int Address;
+ struct sDescriptor_Device DevDesc;
+
int nInterfaces;
tUSBInterface *Interfaces[];
};
}
#endif
#endif
+
+ memcpy(&dev->DevDesc, &desc, sizeof(desc));
}
// TODO: Support alternate configurations
total_length = LittleEndian16(desc.TotalLength);
full_buf = malloc( total_length );
USB_int_ReadDescriptor(dev, 0, 2, i, total_length, full_buf);
-
ptr_ofs += desc.Length;
- // TODO: Interfaces
+
+ // Interfaces!
for( int j = 0; ptr_ofs < total_length && j < desc.NumInterfaces; j ++ )
{
struct sDescriptor_Interface *iface;
LOG("}");
#endif
- dev_if = malloc(sizeof(tUSBInterface) + iface->NumEndpoints*sizeof(dev_if->Endpoints[0]));
+ dev_if = malloc(
+ sizeof(tUSBInterface)
+ + iface->NumEndpoints*sizeof(dev_if->Endpoints[0])
+ );
dev_if->Dev = dev;
dev_if->Driver = NULL;
dev_if->Data = NULL;
dev_if->nEndpoints = iface->NumEndpoints;
+ memcpy(&dev_if->IfaceDesc, iface, sizeof(*iface));
dev->Interfaces[j] = dev_if;
// Copy interface data
--- /dev/null
+/*
+ * Acess 2 USB Stack
+ * - By John Hodge (thePowersGang)
+ *
+ * usb_info.c
+ * - USB Device Information Functions (helpers for drivers)
+ */
+#include <usb_core.h>
+#include "usb.h"
+#include "usb_lowlevel.h"
+
+// === CODE ===
+Uint32 USB_GetInterfaceClass(tUSBInterface *Dev)
+{
+ return ((Uint32)Dev->IfaceDesc.InterfaceClass << 16)
+ |((Uint32)Dev->IfaceDesc.InterfaceSubClass << 8)
+ |((Uint32)Dev->IfaceDesc.InterfaceProtocol << 0);
+}
+
+void USB_GetDeviceVendor(tUSBInterface *Dev, Uint16 *VendorID, Uint16 *DeviceID)
+{
+ *VendorID = LittleEndian16( Dev->Dev->DevDesc.VendorID );
+ *DeviceID = LittleEndian16( Dev->Dev->DevDesc.DeviceID );
+}
+char *USB_GetSerialNumber(tUSBInterface *Dev)
+{
+ return USB_int_GetDeviceString(Dev->Dev, 0, Dev->Dev->DevDesc.SerialNumberStr);
+}
+
ep = &Dev->Endpoints[Endpoint-1];
host = Dev->Dev->Host;
- if( Length > ep->MaxPacketSize ) {
- Log_Warning("USB", "Max packet size exceeded (%i > %i)", ep->MaxPacketSize);
- LEAVE('-');
- }
-
Threads_ClearEvent(THREAD_EVENT_SHORTWAIT);
- host->HostDef->BulkOUT(
- host->Ptr, Dev->Dev->Address*16 + Dev->Endpoints[Endpoint-1].EndpointNum,
- 0, USB_WakeCallback, Proc_GetCurThread(),
- (void*)Data, Length
- );
+ for( size_t ofs = 0; ofs < Length; ofs += ep->MaxPacketSize )
+ {
+ size_t len = MIN(Length - ofs, ep->MaxPacketSize);
+
+ host->HostDef->BulkOUT(
+ host->Ptr, Dev->Dev->Address*16 + Dev->Endpoints[Endpoint-1].EndpointNum,
+ 0, (len == Length - ofs ? USB_WakeCallback : NULL), Proc_GetCurThread(),
+ (char*)Data + ofs, len
+ );
+ }
Threads_WaitEvents(THREAD_EVENT_SHORTWAIT);
LEAVE('-');
ep = &Dev->Endpoints[Endpoint-1];
host = Dev->Dev->Host;
- if( Length > ep->MaxPacketSize ) {
- Log_Warning("USB", "Max packet size exceeded (%i > %i)", ep->MaxPacketSize);
- LEAVE('-');
- }
-
Threads_ClearEvent(THREAD_EVENT_SHORTWAIT);
- host->HostDef->BulkIN(
- host->Ptr, Dev->Dev->Address*16 + Dev->Endpoints[Endpoint-1].EndpointNum,
- 0, USB_WakeCallback, Proc_GetCurThread(),
- Data, Length
- );
+ for( size_t ofs = 0; ofs < Length; ofs += ep->MaxPacketSize )
+ {
+ size_t len = MIN(Length - ofs, ep->MaxPacketSize);
+
+ host->HostDef->BulkIN(
+ host->Ptr, Dev->Dev->Address*16 + Dev->Endpoints[Endpoint-1].EndpointNum,
+ 0, (len == Length - ofs ? USB_WakeCallback : NULL), Proc_GetCurThread(),
+ (char*)Data + ofs, len
+ );
+ }
Threads_WaitEvents(THREAD_EVENT_SHORTWAIT);
LEAVE('-');
}
-void USB_RecvDataA(tUSBInterface *Dev, int Endpoint, int Length, void *DataBuf, tUSB_DataCallback Callback)
+void USB_RecvDataA(tUSBInterface *Dev, int Endpoint, size_t Length, void *DataBuf, tUSB_DataCallback Callback)
{
tAsyncOp *op;
tUSBHost *host;
// TODO: Data toggle
host = Dev->Dev->Host;
+
LOG("IN from %p %i:%i", host->Ptr, Dev->Dev->Address, op->Endpt->EndpointNum);
- host->HostDef->BulkIN(
- host->Ptr, Dev->Dev->Address*16 + op->Endpt->EndpointNum,
- 0, USB_AsyncCallback, op,
- DataBuf, Length
- );
+ for( size_t ofs = 0; ofs < Length; ofs += op->Endpt->MaxPacketSize )
+ {
+ size_t len = MIN(Length - ofs, op->Endpt->MaxPacketSize);
+
+ host->HostDef->BulkIN(
+ host->Ptr, Dev->Dev->Address*16 + op->Endpt->EndpointNum,
+ 0, (len == Length - ofs ? USB_AsyncCallback : NULL), op,
+ (char*)DataBuf + ofs, len
+ );
+ }
LEAVE('-');