A more capable USB Host. The API supports synchronous and Asynchronous control, interrupt and bulk transfers. It has built in support for hubs and hot plugging. It can support any number of devices and endpoints limited only by sram. The test shell supports mouse, keyboard and mass storage/fat.

Dependencies:   mbed

Committer:
peterbarrett1967
Date:
Fri Apr 02 22:28:01 2010 +0000
Revision:
0:5ad808014a49

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
peterbarrett1967 0:5ad808014a49 1
peterbarrett1967 0:5ad808014a49 2 /*
peterbarrett1967 0:5ad808014a49 3 Copyright (c) 2010 Peter Barrett
peterbarrett1967 0:5ad808014a49 4
peterbarrett1967 0:5ad808014a49 5 Permission is hereby granted, free of charge, to any person obtaining a copy
peterbarrett1967 0:5ad808014a49 6 of this software and associated documentation files (the "Software"), to deal
peterbarrett1967 0:5ad808014a49 7 in the Software without restriction, including without limitation the rights
peterbarrett1967 0:5ad808014a49 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
peterbarrett1967 0:5ad808014a49 9 copies of the Software, and to permit persons to whom the Software is
peterbarrett1967 0:5ad808014a49 10 furnished to do so, subject to the following conditions:
peterbarrett1967 0:5ad808014a49 11
peterbarrett1967 0:5ad808014a49 12 The above copyright notice and this permission notice shall be included in
peterbarrett1967 0:5ad808014a49 13 all copies or substantial portions of the Software.
peterbarrett1967 0:5ad808014a49 14
peterbarrett1967 0:5ad808014a49 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
peterbarrett1967 0:5ad808014a49 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
peterbarrett1967 0:5ad808014a49 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
peterbarrett1967 0:5ad808014a49 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
peterbarrett1967 0:5ad808014a49 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
peterbarrett1967 0:5ad808014a49 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
peterbarrett1967 0:5ad808014a49 21 THE SOFTWARE.
peterbarrett1967 0:5ad808014a49 22 */
peterbarrett1967 0:5ad808014a49 23
peterbarrett1967 0:5ad808014a49 24 #include "mbed.h"
peterbarrett1967 0:5ad808014a49 25 #include "USBHost.h"
peterbarrett1967 0:5ad808014a49 26 #include "Utils.h"
peterbarrett1967 0:5ad808014a49 27
peterbarrett1967 0:5ad808014a49 28 #define AUTOEVT(_class,_subclass,_protocol) (((_class) << 16) | ((_subclass) << 8) | _protocol)
peterbarrett1967 0:5ad808014a49 29 #define AUTO_KEYBOARD AUTOEVT(CLASS_HID,1,1)
peterbarrett1967 0:5ad808014a49 30 #define AUTO_MOUSE AUTOEVT(CLASS_HID,1,2)
peterbarrett1967 0:5ad808014a49 31
peterbarrett1967 0:5ad808014a49 32 u8 auto_mouse[4]; // buttons,dx,dy,scroll
peterbarrett1967 0:5ad808014a49 33 u8 auto_keyboard[8]; // modifiers,reserved,keycode1..keycode6
peterbarrett1967 0:5ad808014a49 34 u8 auto_joystick[4]; // x,y,buttons,throttle
peterbarrett1967 0:5ad808014a49 35
peterbarrett1967 0:5ad808014a49 36 void AutoEventCallback(int device, int endpoint, int status, u8* data, int len, void* userData)
peterbarrett1967 0:5ad808014a49 37 {
peterbarrett1967 0:5ad808014a49 38 int evt = (int)userData;
peterbarrett1967 0:5ad808014a49 39 switch (evt)
peterbarrett1967 0:5ad808014a49 40 {
peterbarrett1967 0:5ad808014a49 41 case AUTO_KEYBOARD:
peterbarrett1967 0:5ad808014a49 42 printf("AUTO_KEYBOARD ");
peterbarrett1967 0:5ad808014a49 43 break;
peterbarrett1967 0:5ad808014a49 44 case AUTO_MOUSE:
peterbarrett1967 0:5ad808014a49 45 printf("AUTO_MOUSE ");
peterbarrett1967 0:5ad808014a49 46 break;
peterbarrett1967 0:5ad808014a49 47 default:
peterbarrett1967 0:5ad808014a49 48 printf("HUH ");
peterbarrett1967 0:5ad808014a49 49 }
peterbarrett1967 0:5ad808014a49 50 printfBytes("data",data,len);
peterbarrett1967 0:5ad808014a49 51 USBInterruptTransfer(device,endpoint,data,len,AutoEventCallback,userData);
peterbarrett1967 0:5ad808014a49 52 }
peterbarrett1967 0:5ad808014a49 53
peterbarrett1967 0:5ad808014a49 54 // Establish transfers for interrupt events
peterbarrett1967 0:5ad808014a49 55 void AddAutoEvent(int device, InterfaceDescriptor* id, EndpointDescriptor* ed)
peterbarrett1967 0:5ad808014a49 56 {
peterbarrett1967 0:5ad808014a49 57 if ((ed->bmAttributes & 3) != ENDPOINT_INTERRUPT || !(ed->bEndpointAddress & 0x80))
peterbarrett1967 0:5ad808014a49 58 return;
peterbarrett1967 0:5ad808014a49 59
peterbarrett1967 0:5ad808014a49 60 // Make automatic interrupt enpoints for known devices
peterbarrett1967 0:5ad808014a49 61 u32 evt = AUTOEVT(id->bInterfaceClass,id->bInterfaceSubClass,id->bInterfaceProtocol);
peterbarrett1967 0:5ad808014a49 62 u8* dst = 0;
peterbarrett1967 0:5ad808014a49 63 int len;
peterbarrett1967 0:5ad808014a49 64 switch (evt)
peterbarrett1967 0:5ad808014a49 65 {
peterbarrett1967 0:5ad808014a49 66 case AUTO_MOUSE:
peterbarrett1967 0:5ad808014a49 67 dst = auto_mouse;
peterbarrett1967 0:5ad808014a49 68 len = sizeof(auto_mouse);
peterbarrett1967 0:5ad808014a49 69 break;
peterbarrett1967 0:5ad808014a49 70 case AUTO_KEYBOARD:
peterbarrett1967 0:5ad808014a49 71 dst = auto_keyboard;
peterbarrett1967 0:5ad808014a49 72 len = sizeof(auto_keyboard);
peterbarrett1967 0:5ad808014a49 73 break;
peterbarrett1967 0:5ad808014a49 74 default:
peterbarrett1967 0:5ad808014a49 75 printf("Interrupt endpoint %02X %08X\n",ed->bEndpointAddress,evt);
peterbarrett1967 0:5ad808014a49 76 break;
peterbarrett1967 0:5ad808014a49 77 }
peterbarrett1967 0:5ad808014a49 78 if (dst)
peterbarrett1967 0:5ad808014a49 79 {
peterbarrett1967 0:5ad808014a49 80 printf("Auto Event for %02X %08X\n",ed->bEndpointAddress,evt);
peterbarrett1967 0:5ad808014a49 81 USBInterruptTransfer(device,ed->bEndpointAddress,dst,len,AutoEventCallback,(void*)evt);
peterbarrett1967 0:5ad808014a49 82 }
peterbarrett1967 0:5ad808014a49 83 }
peterbarrett1967 0:5ad808014a49 84
peterbarrett1967 0:5ad808014a49 85 void PrintString(int device, int i)
peterbarrett1967 0:5ad808014a49 86 {
peterbarrett1967 0:5ad808014a49 87 u8 buffer[256];
peterbarrett1967 0:5ad808014a49 88 int le = GetDescriptor(device,DESCRIPTOR_TYPE_STRING,i,buffer,255);
peterbarrett1967 0:5ad808014a49 89 if (le < 0)
peterbarrett1967 0:5ad808014a49 90 return;
peterbarrett1967 0:5ad808014a49 91 char* dst = (char*)buffer;
peterbarrett1967 0:5ad808014a49 92 for (int j = 2; j < le; j += 2)
peterbarrett1967 0:5ad808014a49 93 *dst++ = buffer[j];
peterbarrett1967 0:5ad808014a49 94 *dst = 0;
peterbarrett1967 0:5ad808014a49 95 printf("%d:%s\n",i,(const char*)buffer);
peterbarrett1967 0:5ad808014a49 96 }
peterbarrett1967 0:5ad808014a49 97
peterbarrett1967 0:5ad808014a49 98 // Walk descriptors and create endpoints for a given device
peterbarrett1967 0:5ad808014a49 99 int StartAutoEvent(int device, int configuration, int interfaceNumber)
peterbarrett1967 0:5ad808014a49 100 {
peterbarrett1967 0:5ad808014a49 101 u8 buffer[255];
peterbarrett1967 0:5ad808014a49 102 int err = GetDescriptor(device,DESCRIPTOR_TYPE_CONFIGURATION,0,buffer,255);
peterbarrett1967 0:5ad808014a49 103 if (err < 0)
peterbarrett1967 0:5ad808014a49 104 return err;
peterbarrett1967 0:5ad808014a49 105
peterbarrett1967 0:5ad808014a49 106 int len = buffer[2] | (buffer[3] << 8);
peterbarrett1967 0:5ad808014a49 107 u8* d = buffer;
peterbarrett1967 0:5ad808014a49 108 u8* end = d + len;
peterbarrett1967 0:5ad808014a49 109 while (d < end)
peterbarrett1967 0:5ad808014a49 110 {
peterbarrett1967 0:5ad808014a49 111 if (d[1] == DESCRIPTOR_TYPE_INTERFACE)
peterbarrett1967 0:5ad808014a49 112 {
peterbarrett1967 0:5ad808014a49 113 InterfaceDescriptor* id = (InterfaceDescriptor*)d;
peterbarrett1967 0:5ad808014a49 114 if (id->bInterfaceNumber == interfaceNumber)
peterbarrett1967 0:5ad808014a49 115 {
peterbarrett1967 0:5ad808014a49 116 d += d[0];
peterbarrett1967 0:5ad808014a49 117 while (d < end && d[1] != DESCRIPTOR_TYPE_INTERFACE)
peterbarrett1967 0:5ad808014a49 118 {
peterbarrett1967 0:5ad808014a49 119 if (d[1] == DESCRIPTOR_TYPE_ENDPOINT)
peterbarrett1967 0:5ad808014a49 120 AddAutoEvent(device,id,(EndpointDescriptor*)d);
peterbarrett1967 0:5ad808014a49 121 d += d[0];
peterbarrett1967 0:5ad808014a49 122 }
peterbarrett1967 0:5ad808014a49 123 }
peterbarrett1967 0:5ad808014a49 124 }
peterbarrett1967 0:5ad808014a49 125 d += d[0];
peterbarrett1967 0:5ad808014a49 126 }
peterbarrett1967 0:5ad808014a49 127 return 0;
peterbarrett1967 0:5ad808014a49 128 }
peterbarrett1967 0:5ad808014a49 129
peterbarrett1967 0:5ad808014a49 130 // Implemented in main.cpp
peterbarrett1967 0:5ad808014a49 131 int OnDiskInsert(int device);
peterbarrett1967 0:5ad808014a49 132
peterbarrett1967 0:5ad808014a49 133 void OnLoadDevice(int device, DeviceDescriptor* deviceDesc, InterfaceDescriptor* interfaceDesc)
peterbarrett1967 0:5ad808014a49 134 {
peterbarrett1967 0:5ad808014a49 135 printf("LoadDevice %d %02X:%02X:%02X\n",device,interfaceDesc->bInterfaceClass,interfaceDesc->bInterfaceSubClass,interfaceDesc->bInterfaceProtocol);
peterbarrett1967 0:5ad808014a49 136 char s[128];
peterbarrett1967 0:5ad808014a49 137 for (int i = 1; i < 3; i++)
peterbarrett1967 0:5ad808014a49 138 {
peterbarrett1967 0:5ad808014a49 139 if (GetString(device,i,s,sizeof(s)) < 0)
peterbarrett1967 0:5ad808014a49 140 break;
peterbarrett1967 0:5ad808014a49 141 printf("%d: %s\n",i,s);
peterbarrett1967 0:5ad808014a49 142 }
peterbarrett1967 0:5ad808014a49 143
peterbarrett1967 0:5ad808014a49 144 switch (interfaceDesc->bInterfaceClass)
peterbarrett1967 0:5ad808014a49 145 {
peterbarrett1967 0:5ad808014a49 146 case CLASS_MASS_STORAGE:
peterbarrett1967 0:5ad808014a49 147 if (interfaceDesc->bInterfaceSubClass == 0x06 && interfaceDesc->bInterfaceProtocol == 0x50)
peterbarrett1967 0:5ad808014a49 148 OnDiskInsert(device); // it's SCSI!
peterbarrett1967 0:5ad808014a49 149 break;
peterbarrett1967 0:5ad808014a49 150 default:
peterbarrett1967 0:5ad808014a49 151 StartAutoEvent(device,1,0);
peterbarrett1967 0:5ad808014a49 152 break;
peterbarrett1967 0:5ad808014a49 153 }
peterbarrett1967 0:5ad808014a49 154 }