Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers AutoEvents.cpp Source File

AutoEvents.cpp

00001 
00002 /*
00003 Copyright (c) 2010 Peter Barrett
00004 
00005 Permission is hereby granted, free of charge, to any person obtaining a copy
00006 of this software and associated documentation files (the "Software"), to deal
00007 in the Software without restriction, including without limitation the rights
00008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00009 copies of the Software, and to permit persons to whom the Software is
00010 furnished to do so, subject to the following conditions:
00011 
00012 The above copyright notice and this permission notice shall be included in
00013 all copies or substantial portions of the Software.
00014 
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00018 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00019 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00020 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00021 THE SOFTWARE.
00022 */
00023 
00024 #include "mbed.h"
00025 #include "USBHost.h"
00026 #include "Utils.h"
00027 #include "Terminal.h"
00028 
00029 
00030 #define AUTOEVT(_class,_subclass,_protocol) (((_class) << 16) | ((_subclass) << 8) | _protocol)
00031 #define AUTO_KEYBOARD AUTOEVT(CLASS_HID,1,1)
00032 #define AUTO_MOUSE AUTOEVT(CLASS_HID,1,2)
00033 
00034 u8 auto_mouse[4];       // buttons,dx,dy,scroll
00035 u8 auto_keyboard[8];    // modifiers,reserved,keycode1..keycode6
00036 u8 auto_joystick[4];    // x,y,buttons,throttle
00037 
00038 void AutoEventCallback(int device, int endpoint, int status, u8* data, int len, void* userData)
00039 {
00040     int evt = (int)userData;
00041     switch (evt)
00042     {
00043         case AUTO_KEYBOARD:
00044             pc.printf("AUTO_KEYBOARD ");
00045             break;
00046         case AUTO_MOUSE:
00047             pc.printf("AUTO_MOUSE ");
00048             break;
00049         default:
00050             pc.printf("HUH ");
00051     }
00052     printfBytes("data",data,len);
00053     USBInterruptTransfer(device,endpoint,data,len,AutoEventCallback,userData);
00054 }
00055 
00056 //  Establish transfers for interrupt events
00057 void AddAutoEvent(int device, InterfaceDescriptor* id, EndpointDescriptor* ed)
00058 {
00059     if ((ed->bmAttributes & 3) != ENDPOINT_INTERRUPT || !(ed->bEndpointAddress & 0x80))
00060         return;
00061     
00062     // Make automatic interrupt enpoints for known devices
00063     u32 evt = AUTOEVT(id->bInterfaceClass,id->bInterfaceSubClass,id->bInterfaceProtocol);
00064     u8* dst = 0;
00065     int len;
00066     switch (evt)
00067     {
00068         case AUTO_MOUSE:
00069             dst = auto_mouse;
00070             len = sizeof(auto_mouse);
00071             break;
00072         case AUTO_KEYBOARD:
00073             dst = auto_keyboard;
00074             len = sizeof(auto_keyboard);
00075             break;
00076         default:
00077             pc.printf("Interrupt endpoint %02X %08X\r\n",ed->bEndpointAddress,evt);
00078             break;
00079     }
00080     if (dst)
00081     {
00082         pc.printf("Auto Event for %02X %08X\r\n",ed->bEndpointAddress,evt);
00083         USBInterruptTransfer(device,ed->bEndpointAddress,dst,len,AutoEventCallback,(void*)evt);
00084     }
00085 }
00086 
00087 void PrintString(int device, int i)
00088 {
00089     u8 buffer[256];
00090     int le = GetDescriptor(device,DESCRIPTOR_TYPE_STRING,i,buffer,255);
00091     if (le < 0)
00092          return;
00093     char* dst = (char*)buffer;
00094     for (int j = 2; j < le; j += 2)
00095         *dst++ = buffer[j];
00096     *dst = 0;d
00097     
00098     
00099     pc.printf("%d:%s\r\n",i,(const char*)buffer);
00100  }
00101  
00102 //  Walk descriptors and create endpoints for a given device
00103 int StartAutoEvent(int device, int configuration, int interfaceNumber)
00104 {
00105     u8 buffer[255];
00106     int err = GetDescriptor(device,DESCRIPTOR_TYPE_CONFIGURATION,0,buffer,255);
00107     if (err < 0)
00108         return err;
00109 
00110     int len = buffer[2] | (buffer[3] << 8);
00111     u8* d = buffer;
00112     u8* end = d + len;
00113     while (d < end)
00114     {
00115         if (d[1] == DESCRIPTOR_TYPE_INTERFACE)
00116         {
00117             InterfaceDescriptor* id = (InterfaceDescriptor*)d;
00118             if (id->bInterfaceNumber == interfaceNumber)
00119             {
00120                  d += d[0];
00121                 while (d < end && d[1] != DESCRIPTOR_TYPE_INTERFACE)
00122                 {
00123                     if (d[1] == DESCRIPTOR_TYPE_ENDPOINT)
00124                         AddAutoEvent(device,id,(EndpointDescriptor*)d);
00125                     d += d[0];
00126                 }
00127             }
00128         }
00129         d += d[0];
00130     }
00131     return 0;
00132 }
00133 
00134 //  Implemented in main.cpp
00135 int OnDiskInsert(int device)
00136 {
00137     pc.printf("\r\nOn Disk Insert Device %d\r\n",device);
00138     
00139     USB_Disk_Device = device;
00140     USB_Disk_Detected = 1;
00141    
00142    return 0;         
00143 }
00144 
00145 EndpointDescriptor* GetNextEndpoint(unsigned char *d) {
00146     while (d) {
00147         switch (d[1]) {
00148             case DESCRIPTOR_TYPE_INTERFACE:
00149             case DESCRIPTOR_TYPE_CONFIGURATION:
00150                 return 0;
00151             case DESCRIPTOR_TYPE_ENDPOINT:
00152                 return (EndpointDescriptor*)d;
00153             default:
00154                 printf("Skipping descriptor %02X (%d bytes)\n",d[1],d[0]);
00155         }
00156         d += d[0];
00157     }
00158     return 0;
00159 }
00160 
00161 EndpointDescriptor* GetEndpoint(InterfaceDescriptor* interfaceDesc, int i) {
00162     unsigned char *d = (unsigned char*)interfaceDesc;
00163     int n = interfaceDesc->bNumEndpoints;
00164     int j = 0;
00165     if (i >= n)
00166         return 0;
00167     d += d[0];//move to first descriptor after the interface descriptor
00168     while (j < n) {
00169         switch (d[1]) {
00170             case DESCRIPTOR_TYPE_INTERFACE:
00171             case DESCRIPTOR_TYPE_CONFIGURATION:
00172                 return 0;
00173             case DESCRIPTOR_TYPE_ENDPOINT:
00174                 if (i == j)
00175                     return (EndpointDescriptor*)d;
00176                 j++;
00177                 break;
00178             default:
00179                 printf("Skipping descriptor %02X (%d bytes)\n",d[1],d[0]);
00180         }
00181         d += d[0];
00182     }
00183     return 0;
00184 }
00185 
00186 void OnLoadDevice(int device, DeviceDescriptor* deviceDesc, InterfaceDescriptor* interfaceDesc)
00187 {
00188     pc.printf("LoadDevice %d %02X:%02X:%02X\r\n",device,interfaceDesc->bInterfaceClass,interfaceDesc->bInterfaceSubClass,interfaceDesc->bInterfaceProtocol);
00189     char s[128];
00190     for (int i = 1; i < 3; i++)
00191     {
00192         if (GetString(device,i,s,sizeof(s)) < 0)
00193             break;
00194         pc.printf("%d: %s\r\n",i,s);
00195     }
00196     
00197     switch (interfaceDesc->bInterfaceClass)
00198     {
00199         case CLASS_MASS_STORAGE:
00200            
00201            
00202             pc.printf("interfaceDesc->bInterfaceSubClass %X\r\n",interfaceDesc->bInterfaceSubClass);
00203             pc.printf("interfaceDesc->bInterfaceProtocol %X\r\n",interfaceDesc->bInterfaceProtocol);
00204             
00205              if (interfaceDesc->bInterfaceSubClass == 0x06 && interfaceDesc->bInterfaceProtocol == 0x50)
00206               {
00207                 unsigned char epin = 0x81;
00208                 unsigned char epout = 0x01;
00209                 for (int i = 0; i < interfaceDesc->bNumEndpoints; i++)
00210                 {
00211                    EndpointDescriptor* ep = GetEndpoint(interfaceDesc, i);
00212                    if (ep){
00213                      if (ep->bEndpointAddress & 0x7F)
00214                         if (ep->bEndpointAddress & 0x80)
00215                           epin = ep->bEndpointAddress;
00216                         else
00217                           epout = ep->bEndpointAddress;
00218                       }else break;
00219                 }
00220                    OnDiskInsert(device);    // it's SCSI!
00221                     pc.printf("In = %02X, Out = %02X\r\n", epin, epout);
00222                     SetSCSIEndPoints(epin,epout);
00223                } 
00224         
00225     
00226         default:
00227             StartAutoEvent(device,1,0);
00228             break;
00229     }
00230 }