this is the Peter Barrett USBHostShell program, a bit modified for being a bit more talkactive, just to let u know how the USB protocol layer is going on, and all the data trasnfers. Also there is a small implementation of HID descriptors, but not functional... yet :S the aim is to at least implement the gamepad HID, and make an array of function pointer to each HID function

Dependencies:   mbed

Revision:
0:e1e03118b8fe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HID.cpp	Mon Sep 13 12:40:05 2010 +0000
@@ -0,0 +1,345 @@
+
+
+#include "mbed.h"
+#include "HID.h"
+
+
+
+const char ItemSize[4]={0,1,2,4};
+
+void ResetParser(HIDParser* pParser)
+{
+    pParser->Pos=0;
+    pParser->Count=0;
+    pParser->nObject=0;
+    pParser->nReport=0;
+    pParser->UsageSize=0;
+    memset(pParser->UsageTab,0,sizeof(pParser->UsageTab));
+    memset(pParser->OffsetTab,0,sizeof(pParser->OffsetTab));
+    memset(&pParser->Data,0,sizeof(pParser->Data));
+}
+    
+static void ResetLocalState(HIDParser* pParser)
+{
+    pParser->UsageSize=0;
+    memset(pParser->UsageTab,0,sizeof(pParser->UsageTab));
+}
+    
+u8* GetReportOffset(HIDParser* pParser, 
+                        const u8 ReportID, 
+                        const u8 ReportType)
+ {
+   u8 Pos=0;
+   while(Pos<MAX_REPORT && pParser->OffsetTab[Pos][0]!=0)
+   {
+     if(pParser->OffsetTab[Pos][0]==ReportID 
+       && pParser->OffsetTab[Pos][1]==ReportType)
+       return &pParser->OffsetTab[Pos][2];
+     Pos++;
+   }
+   if(Pos<MAX_REPORT)
+   {
+     /* Increment Report count */
+     pParser->nReport++;
+     pParser->OffsetTab[Pos][0]=ReportID;
+     pParser->OffsetTab[Pos][1]=ReportType;
+     pParser->OffsetTab[Pos][2]=0;
+     return &pParser->OffsetTab[Pos][2];
+   }
+   return NULL;
+ }    
+    
+    
+long FormatValue(long Value, char Size)
+ {
+   if(Size==1) 
+     Value=(long)(char)Value;
+   else if(Size==2) 
+     Value=(long)(short)Value;
+   return Value;
+ }
+
+ int HIDParse(HIDParser* pParser, HIDData* pData)
+ {
+   int Found=0;
+ 
+   while(!Found && pParser->Pos<pParser->ReportDescSize)
+   {
+     /* Get new pParser->Item if current pParser->Count is empty */
+     if(pParser->Count==0)
+     {
+       pParser->Item=pParser->ReportDesc[pParser->Pos++];
+       pParser->Value=0;
+
+       memcpy(&pParser->Value, &pParser->ReportDesc[pParser->Pos], ItemSize[pParser->Item & SIZE_MASK]);
+
+       /* Pos on next item */
+       pParser->Pos+=ItemSize[pParser->Item & SIZE_MASK];
+     }
+ 
+     switch(pParser->Item & ITEM_MASK)
+     {
+       case ITEM_UPAGE :
+       {
+         /* Copy UPage in Usage stack */
+         pParser->UPage=(u8)pParser->Value;
+         break;
+       }
+       case ITEM_USAGE :
+       {
+         /* Copy global or local UPage if any, in Usage stack */
+          if((pParser->Item & SIZE_MASK)>2)
+          pParser->UsageTab[pParser->UsageSize].UPage=(u8)(pParser->Value>>16);
+         else
+          pParser->UsageTab[pParser->UsageSize].UPage=pParser->UPage;
+ 
+         /* Copy Usage in Usage stack */
+         pParser->UsageTab[pParser->UsageSize].Usage=(u8)(pParser->Value & 0xFFFF);
+ 
+         /* Increment Usage stack size */
+         pParser->UsageSize++;
+ 
+         break;
+       }
+       case ITEM_COLLECTION :
+       {
+         /* Get UPage/Usage from UsageTab and store them in pParser->Data.Path */
+         pParser->Data.Path.Node[pParser->Data.Path.Size].UPage=pParser->UsageTab[0].UPage;
+         pParser->Data.Path.Node[pParser->Data.Path.Size].Usage=pParser->UsageTab[0].Usage;
+         pParser->Data.Path.Size++;
+       
+         /* Unstack UPage/Usage from UsageTab (never remove the last) */
+         if(pParser->UsageSize>0)
+         {
+           u8 ii=0;
+           while(ii<pParser->UsageSize)
+           {
+             pParser->UsageTab[ii].Usage=pParser->UsageTab[ii+1].Usage;
+             pParser->UsageTab[ii].UPage=pParser->UsageTab[ii+1].UPage;
+            ii++;
+           }
+           /* Remove Usage */
+           pParser->UsageSize--;
+         }
+
+         /* Get Index if any */
+         if(pParser->Value>=0x80)
+         {
+           pParser->Data.Path.Node[pParser->Data.Path.Size].UPage=0xFF;
+           pParser->Data.Path.Node[pParser->Data.Path.Size].Usage=pParser->Value & 0x7F;
+           pParser->Data.Path.Size++;
+       }
+   ResetLocalState(pParser);
+      break;
+       }
+     case ITEM_END_COLLECTION :
+       {
+         pParser->Data.Path.Size--;
+         /* Remove Index if any */
+         if(pParser->Data.Path.Node[pParser->Data.Path.Size].UPage==0xFF)
+           pParser->Data.Path.Size--;
+   ResetLocalState(pParser);
+         break;
+       }
+       case ITEM_FEATURE :
+       case ITEM_INPUT :
+       case ITEM_OUTPUT :
+       {
+         /* An object was found */
+         Found=1;
+ 
+         /* Increment object count */
+         pParser->nObject++;
+
+     /* Get new pParser->Count from global value */
+      if(pParser->Count==0)
+     {
+        pParser->Count=pParser->ReportCount;
+       }
+
+    /* Get UPage/Usage from UsageTab and store them in pParser->Data.Path */
+        pParser->Data.Path.Node[pParser->Data.Path.Size].UPage=pParser->UsageTab[0].UPage;
+         pParser->Data.Path.Node[pParser->Data.Path.Size].Usage=pParser->UsageTab[0].Usage;
+         pParser->Data.Path.Size++;
+
+         /* Unstack UPage/Usage from UsageTab (never remove the last) */
+         if(pParser->UsageSize>0)
+         {
+           u8 ii=0;
+           while(ii<pParser->UsageSize)
+           {
+             pParser->UsageTab[ii].UPage=pParser->UsageTab[ii+1].UPage;
+             pParser->UsageTab[ii].Usage=pParser->UsageTab[ii+1].Usage;
+             ii++;
+           }
+           /* Remove Usage */
+           pParser->UsageSize--;
+         }
+ 
+         /* Copy data type */
+         pParser->Data.Type=(u8)(pParser->Item & ITEM_MASK);
+ 
+         /* Copy data attribute */
+        pParser->Data.Attribute=(u8)pParser->Value;
+ 
+         /* Store offset */
+         pParser->Data.Offset=*GetReportOffset(pParser, pParser->Data.ReportID, (u8)(pParser->Item & ITEM_MASK));
+     
+         /* Get Object in pData */
+         /* -------------------------------------------------------------------------- */
+         memcpy(pData, &pParser->Data, sizeof(HIDData));
+         /* -------------------------------------------------------------------------- */
+ 
+         /* Increment Report Offset */
+         *GetReportOffset(pParser, pParser->Data.ReportID, (u8)(pParser->Item & ITEM_MASK)) += pParser->Data.Size;
+ 
+         /* Remove path last node */
+         pParser->Data.Path.Size--;
+ 
+         /* Decrement count */
+         pParser->Count--;
+  if (pParser->Count == 0) {
+    ResetLocalState(pParser);
+   }
+        break;
+       }
+       case ITEM_REP_ID :
+       {
+        pParser->Data.ReportID=(u8)pParser->Value;
+        break;
+       }
+       case ITEM_REP_SIZE :
+       {
+         pParser->Data.Size=(u8)pParser->Value;
+         break;
+       }
+       case ITEM_REP_COUNT :
+       {
+        pParser->ReportCount=(u8)pParser->Value;
+         break;
+       }
+       case ITEM_UNIT_EXP :
+       {
+         pParser->Data.UnitExp=(char)pParser->Value;
+   // Convert 4 bits signed value to 8 bits signed value
+   if (pParser->Data.UnitExp > 7)
+     pParser->Data.UnitExp|=0xF0;
+         break;
+     }
+       case ITEM_UNIT :
+      {
+        pParser->Data.Unit=pParser->Value;
+         break;
+       }
+       case ITEM_LOG_MIN :
+       {
+         pParser->Data.LogMin=FormatValue(pParser->Value, ItemSize[pParser->Item & SIZE_MASK]);
+         break;
+       }
+       case ITEM_LOG_MAX :
+       {
+         pParser->Data.LogMax=FormatValue(pParser->Value, ItemSize[pParser->Item & SIZE_MASK]);
+         break;
+       }
+       case ITEM_PHY_MIN :
+       {
+        pParser->Data.PhyMin=FormatValue(pParser->Value, ItemSize[pParser->Item & SIZE_MASK]);
+         break;
+       }
+       case ITEM_PHY_MAX :
+       {
+         pParser->Data.PhyMax=FormatValue(pParser->Value, ItemSize[pParser->Item & SIZE_MASK]);
+         break;
+       }
+       case ITEM_LONG :
+       {
+   /* can't handle long items, but should at least skip them */
+   pParser->Pos+=(u8)(pParser->Value & 0xff);
+       }
+    }
+   } /* while(!Found && pParser->Pos<pParser->ReportDescSize) */
+ 
+/*   ERROR(pParser->Data.Path.Size>=PATH_SIZE);
+   ERROR(pParser->ReportDescSize>=REPORT_DSC_SIZE);
+   ERROR(pParser->UsageSize>=USAGE_TAB_SIZE);
+   ERROR(pParser->Data.ReportID>=MAX_REPORT);
+ */
+   return Found;
+ }
+ 
+ int FindObject(HIDParser* pParser, HIDData* pData)
+ {
+   HIDData FoundData;
+   ResetParser(pParser);
+   while(HIDParse(pParser, &FoundData))
+   {
+     if(pData->Path.Size>0 && 
+       FoundData.Type==pData->Type &&
+       memcmp(FoundData.Path.Node, pData->Path.Node, (pData->Path.Size)*sizeof(HIDNode))==0)
+     {
+       memcpy(pData, &FoundData, sizeof(HIDData));
+       return 1;
+     }
+     /* Found by ReportID/Offset */
+     else if(FoundData.ReportID==pData->ReportID && 
+       FoundData.Type==pData->Type &&
+       FoundData.Offset==pData->Offset)
+     {
+       memcpy(pData, &FoundData, sizeof(HIDData));
+       return 1;
+     }
+   }
+   return 0;
+ }
+ 
+ void GetValue(const u8* Buf, HIDData* pData)
+ {
+   int Bit=pData->Offset+8; /* First byte of report indicate report ID */
+   int Weight=0;
+   pData->Value=0;
+ 
+  while(Weight<pData->Size)
+   {
+     int State=Buf[Bit>>3]&(1<<(Bit%8));
+     if(State)
+    {
+       pData->Value+=(1<<Weight);
+     }
+     Weight++;
+    Bit++;
+   }
+ /*  if(pData->Value > pData->LogMax)
+     pData->Value=FormatValue(pData->Value, (uchar)((pData->Size-1)/8+1));
+ */
+   if (pData->Value > pData->LogMax)
+     pData->Value |= ~pData->LogMax;
+ }
+ 
+ void SetValue(const HIDData* pData, u8* Buf)
+ {
+  int Bit=pData->Offset+8; /* First byte of report indicate report ID */
+  int Weight=0;
+ 
+   while(Weight<pData->Size)
+   {
+     int State=pData->Value & (1<<Weight);
+     
+     if(Bit%8==0)
+       Buf[Bit/8]=0;
+ 
+     if(State)
+     {
+      Buf[Bit/8]+=(1<<(Weight%8));
+     }
+     Weight++;
+     Bit++;
+   }
+ }
+
+
+
+
+
+
+
+    
\ No newline at end of file