Dependencies:   mbed

Committer:
emh203
Date:
Thu Feb 16 00:41:26 2012 +0000
Revision:
0:76427232f435

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
emh203 0:76427232f435 1
emh203 0:76427232f435 2 /*
emh203 0:76427232f435 3 Copyright (c) 2010 Peter Barrett
emh203 0:76427232f435 4
emh203 0:76427232f435 5 Permission is hereby granted, free of charge, to any person obtaining a copy
emh203 0:76427232f435 6 of this software and associated documentation files (the "Software"), to deal
emh203 0:76427232f435 7 in the Software without restriction, including without limitation the rights
emh203 0:76427232f435 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
emh203 0:76427232f435 9 copies of the Software, and to permit persons to whom the Software is
emh203 0:76427232f435 10 furnished to do so, subject to the following conditions:
emh203 0:76427232f435 11
emh203 0:76427232f435 12 The above copyright notice and this permission notice shall be included in
emh203 0:76427232f435 13 all copies or substantial portions of the Software.
emh203 0:76427232f435 14
emh203 0:76427232f435 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
emh203 0:76427232f435 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
emh203 0:76427232f435 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
emh203 0:76427232f435 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
emh203 0:76427232f435 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
emh203 0:76427232f435 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
emh203 0:76427232f435 21 THE SOFTWARE.
emh203 0:76427232f435 22 */
emh203 0:76427232f435 23
emh203 0:76427232f435 24 #include "mbed.h"
emh203 0:76427232f435 25 #include "USBHost.h"
emh203 0:76427232f435 26 #include "Utils.h"
emh203 0:76427232f435 27 #include "Terminal.h"
emh203 0:76427232f435 28
emh203 0:76427232f435 29
emh203 0:76427232f435 30 #define AUTOEVT(_class,_subclass,_protocol) (((_class) << 16) | ((_subclass) << 8) | _protocol)
emh203 0:76427232f435 31 #define AUTO_KEYBOARD AUTOEVT(CLASS_HID,1,1)
emh203 0:76427232f435 32 #define AUTO_MOUSE AUTOEVT(CLASS_HID,1,2)
emh203 0:76427232f435 33
emh203 0:76427232f435 34 u8 auto_mouse[4]; // buttons,dx,dy,scroll
emh203 0:76427232f435 35 u8 auto_keyboard[8]; // modifiers,reserved,keycode1..keycode6
emh203 0:76427232f435 36 u8 auto_joystick[4]; // x,y,buttons,throttle
emh203 0:76427232f435 37
emh203 0:76427232f435 38 void AutoEventCallback(int device, int endpoint, int status, u8* data, int len, void* userData)
emh203 0:76427232f435 39 {
emh203 0:76427232f435 40 int evt = (int)userData;
emh203 0:76427232f435 41 switch (evt)
emh203 0:76427232f435 42 {
emh203 0:76427232f435 43 case AUTO_KEYBOARD:
emh203 0:76427232f435 44 pc.printf("AUTO_KEYBOARD ");
emh203 0:76427232f435 45 break;
emh203 0:76427232f435 46 case AUTO_MOUSE:
emh203 0:76427232f435 47 pc.printf("AUTO_MOUSE ");
emh203 0:76427232f435 48 break;
emh203 0:76427232f435 49 default:
emh203 0:76427232f435 50 pc.printf("HUH ");
emh203 0:76427232f435 51 }
emh203 0:76427232f435 52 printfBytes("data",data,len);
emh203 0:76427232f435 53 USBInterruptTransfer(device,endpoint,data,len,AutoEventCallback,userData);
emh203 0:76427232f435 54 }
emh203 0:76427232f435 55
emh203 0:76427232f435 56 // Establish transfers for interrupt events
emh203 0:76427232f435 57 void AddAutoEvent(int device, InterfaceDescriptor* id, EndpointDescriptor* ed)
emh203 0:76427232f435 58 {
emh203 0:76427232f435 59 if ((ed->bmAttributes & 3) != ENDPOINT_INTERRUPT || !(ed->bEndpointAddress & 0x80))
emh203 0:76427232f435 60 return;
emh203 0:76427232f435 61
emh203 0:76427232f435 62 // Make automatic interrupt enpoints for known devices
emh203 0:76427232f435 63 u32 evt = AUTOEVT(id->bInterfaceClass,id->bInterfaceSubClass,id->bInterfaceProtocol);
emh203 0:76427232f435 64 u8* dst = 0;
emh203 0:76427232f435 65 int len;
emh203 0:76427232f435 66 switch (evt)
emh203 0:76427232f435 67 {
emh203 0:76427232f435 68 case AUTO_MOUSE:
emh203 0:76427232f435 69 dst = auto_mouse;
emh203 0:76427232f435 70 len = sizeof(auto_mouse);
emh203 0:76427232f435 71 break;
emh203 0:76427232f435 72 case AUTO_KEYBOARD:
emh203 0:76427232f435 73 dst = auto_keyboard;
emh203 0:76427232f435 74 len = sizeof(auto_keyboard);
emh203 0:76427232f435 75 break;
emh203 0:76427232f435 76 default:
emh203 0:76427232f435 77 pc.printf("Interrupt endpoint %02X %08X\r\n",ed->bEndpointAddress,evt);
emh203 0:76427232f435 78 break;
emh203 0:76427232f435 79 }
emh203 0:76427232f435 80 if (dst)
emh203 0:76427232f435 81 {
emh203 0:76427232f435 82 pc.printf("Auto Event for %02X %08X\r\n",ed->bEndpointAddress,evt);
emh203 0:76427232f435 83 USBInterruptTransfer(device,ed->bEndpointAddress,dst,len,AutoEventCallback,(void*)evt);
emh203 0:76427232f435 84 }
emh203 0:76427232f435 85 }
emh203 0:76427232f435 86
emh203 0:76427232f435 87 void PrintString(int device, int i)
emh203 0:76427232f435 88 {
emh203 0:76427232f435 89 u8 buffer[256];
emh203 0:76427232f435 90 int le = GetDescriptor(device,DESCRIPTOR_TYPE_STRING,i,buffer,255);
emh203 0:76427232f435 91 if (le < 0)
emh203 0:76427232f435 92 return;
emh203 0:76427232f435 93 char* dst = (char*)buffer;
emh203 0:76427232f435 94 for (int j = 2; j < le; j += 2)
emh203 0:76427232f435 95 *dst++ = buffer[j];
emh203 0:76427232f435 96 *dst = 0;d
emh203 0:76427232f435 97
emh203 0:76427232f435 98
emh203 0:76427232f435 99 pc.printf("%d:%s\r\n",i,(const char*)buffer);
emh203 0:76427232f435 100 }
emh203 0:76427232f435 101
emh203 0:76427232f435 102 // Walk descriptors and create endpoints for a given device
emh203 0:76427232f435 103 int StartAutoEvent(int device, int configuration, int interfaceNumber)
emh203 0:76427232f435 104 {
emh203 0:76427232f435 105 u8 buffer[255];
emh203 0:76427232f435 106 int err = GetDescriptor(device,DESCRIPTOR_TYPE_CONFIGURATION,0,buffer,255);
emh203 0:76427232f435 107 if (err < 0)
emh203 0:76427232f435 108 return err;
emh203 0:76427232f435 109
emh203 0:76427232f435 110 int len = buffer[2] | (buffer[3] << 8);
emh203 0:76427232f435 111 u8* d = buffer;
emh203 0:76427232f435 112 u8* end = d + len;
emh203 0:76427232f435 113 while (d < end)
emh203 0:76427232f435 114 {
emh203 0:76427232f435 115 if (d[1] == DESCRIPTOR_TYPE_INTERFACE)
emh203 0:76427232f435 116 {
emh203 0:76427232f435 117 InterfaceDescriptor* id = (InterfaceDescriptor*)d;
emh203 0:76427232f435 118 if (id->bInterfaceNumber == interfaceNumber)
emh203 0:76427232f435 119 {
emh203 0:76427232f435 120 d += d[0];
emh203 0:76427232f435 121 while (d < end && d[1] != DESCRIPTOR_TYPE_INTERFACE)
emh203 0:76427232f435 122 {
emh203 0:76427232f435 123 if (d[1] == DESCRIPTOR_TYPE_ENDPOINT)
emh203 0:76427232f435 124 AddAutoEvent(device,id,(EndpointDescriptor*)d);
emh203 0:76427232f435 125 d += d[0];
emh203 0:76427232f435 126 }
emh203 0:76427232f435 127 }
emh203 0:76427232f435 128 }
emh203 0:76427232f435 129 d += d[0];
emh203 0:76427232f435 130 }
emh203 0:76427232f435 131 return 0;
emh203 0:76427232f435 132 }
emh203 0:76427232f435 133
emh203 0:76427232f435 134 // Implemented in main.cpp
emh203 0:76427232f435 135 int OnDiskInsert(int device)
emh203 0:76427232f435 136 {
emh203 0:76427232f435 137 pc.printf("\r\nOn Disk Insert Device %d\r\n",device);
emh203 0:76427232f435 138
emh203 0:76427232f435 139 USB_Disk_Device = device;
emh203 0:76427232f435 140 USB_Disk_Detected = 1;
emh203 0:76427232f435 141
emh203 0:76427232f435 142 return 0;
emh203 0:76427232f435 143 }
emh203 0:76427232f435 144
emh203 0:76427232f435 145 EndpointDescriptor* GetNextEndpoint(unsigned char *d) {
emh203 0:76427232f435 146 while (d) {
emh203 0:76427232f435 147 switch (d[1]) {
emh203 0:76427232f435 148 case DESCRIPTOR_TYPE_INTERFACE:
emh203 0:76427232f435 149 case DESCRIPTOR_TYPE_CONFIGURATION:
emh203 0:76427232f435 150 return 0;
emh203 0:76427232f435 151 case DESCRIPTOR_TYPE_ENDPOINT:
emh203 0:76427232f435 152 return (EndpointDescriptor*)d;
emh203 0:76427232f435 153 default:
emh203 0:76427232f435 154 printf("Skipping descriptor %02X (%d bytes)\n",d[1],d[0]);
emh203 0:76427232f435 155 }
emh203 0:76427232f435 156 d += d[0];
emh203 0:76427232f435 157 }
emh203 0:76427232f435 158 return 0;
emh203 0:76427232f435 159 }
emh203 0:76427232f435 160
emh203 0:76427232f435 161 EndpointDescriptor* GetEndpoint(InterfaceDescriptor* interfaceDesc, int i) {
emh203 0:76427232f435 162 unsigned char *d = (unsigned char*)interfaceDesc;
emh203 0:76427232f435 163 int n = interfaceDesc->bNumEndpoints;
emh203 0:76427232f435 164 int j = 0;
emh203 0:76427232f435 165 if (i >= n)
emh203 0:76427232f435 166 return 0;
emh203 0:76427232f435 167 d += d[0];//move to first descriptor after the interface descriptor
emh203 0:76427232f435 168 while (j < n) {
emh203 0:76427232f435 169 switch (d[1]) {
emh203 0:76427232f435 170 case DESCRIPTOR_TYPE_INTERFACE:
emh203 0:76427232f435 171 case DESCRIPTOR_TYPE_CONFIGURATION:
emh203 0:76427232f435 172 return 0;
emh203 0:76427232f435 173 case DESCRIPTOR_TYPE_ENDPOINT:
emh203 0:76427232f435 174 if (i == j)
emh203 0:76427232f435 175 return (EndpointDescriptor*)d;
emh203 0:76427232f435 176 j++;
emh203 0:76427232f435 177 break;
emh203 0:76427232f435 178 default:
emh203 0:76427232f435 179 printf("Skipping descriptor %02X (%d bytes)\n",d[1],d[0]);
emh203 0:76427232f435 180 }
emh203 0:76427232f435 181 d += d[0];
emh203 0:76427232f435 182 }
emh203 0:76427232f435 183 return 0;
emh203 0:76427232f435 184 }
emh203 0:76427232f435 185
emh203 0:76427232f435 186 void OnLoadDevice(int device, DeviceDescriptor* deviceDesc, InterfaceDescriptor* interfaceDesc)
emh203 0:76427232f435 187 {
emh203 0:76427232f435 188 pc.printf("LoadDevice %d %02X:%02X:%02X\r\n",device,interfaceDesc->bInterfaceClass,interfaceDesc->bInterfaceSubClass,interfaceDesc->bInterfaceProtocol);
emh203 0:76427232f435 189 char s[128];
emh203 0:76427232f435 190 for (int i = 1; i < 3; i++)
emh203 0:76427232f435 191 {
emh203 0:76427232f435 192 if (GetString(device,i,s,sizeof(s)) < 0)
emh203 0:76427232f435 193 break;
emh203 0:76427232f435 194 pc.printf("%d: %s\r\n",i,s);
emh203 0:76427232f435 195 }
emh203 0:76427232f435 196
emh203 0:76427232f435 197 switch (interfaceDesc->bInterfaceClass)
emh203 0:76427232f435 198 {
emh203 0:76427232f435 199 case CLASS_MASS_STORAGE:
emh203 0:76427232f435 200
emh203 0:76427232f435 201
emh203 0:76427232f435 202 pc.printf("interfaceDesc->bInterfaceSubClass %X\r\n",interfaceDesc->bInterfaceSubClass);
emh203 0:76427232f435 203 pc.printf("interfaceDesc->bInterfaceProtocol %X\r\n",interfaceDesc->bInterfaceProtocol);
emh203 0:76427232f435 204
emh203 0:76427232f435 205 if (interfaceDesc->bInterfaceSubClass == 0x06 && interfaceDesc->bInterfaceProtocol == 0x50)
emh203 0:76427232f435 206 {
emh203 0:76427232f435 207 unsigned char epin = 0x81;
emh203 0:76427232f435 208 unsigned char epout = 0x01;
emh203 0:76427232f435 209 for (int i = 0; i < interfaceDesc->bNumEndpoints; i++)
emh203 0:76427232f435 210 {
emh203 0:76427232f435 211 EndpointDescriptor* ep = GetEndpoint(interfaceDesc, i);
emh203 0:76427232f435 212 if (ep){
emh203 0:76427232f435 213 if (ep->bEndpointAddress & 0x7F)
emh203 0:76427232f435 214 if (ep->bEndpointAddress & 0x80)
emh203 0:76427232f435 215 epin = ep->bEndpointAddress;
emh203 0:76427232f435 216 else
emh203 0:76427232f435 217 epout = ep->bEndpointAddress;
emh203 0:76427232f435 218 }else break;
emh203 0:76427232f435 219 }
emh203 0:76427232f435 220 OnDiskInsert(device); // it's SCSI!
emh203 0:76427232f435 221 pc.printf("In = %02X, Out = %02X\r\n", epin, epout);
emh203 0:76427232f435 222 SetSCSIEndPoints(epin,epout);
emh203 0:76427232f435 223 }
emh203 0:76427232f435 224
emh203 0:76427232f435 225
emh203 0:76427232f435 226 default:
emh203 0:76427232f435 227 StartAutoEvent(device,1,0);
emh203 0:76427232f435 228 break;
emh203 0:76427232f435 229 }
emh203 0:76427232f435 230 }