Sergio Collado / Mbed 2 deprecated USBHostShell_HID_talkactive_alpha

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HID.cpp Source File

HID.cpp

00001 
00002 
00003 #include "mbed.h"
00004 #include "HID.h"
00005 
00006 
00007 
00008 const char ItemSize[4]={0,1,2,4};
00009 
00010 void ResetParser(HIDParser* pParser)
00011 {
00012     pParser->Pos=0;
00013     pParser->Count=0;
00014     pParser->nObject=0;
00015     pParser->nReport=0;
00016     pParser->UsageSize=0;
00017     memset(pParser->UsageTab,0,sizeof(pParser->UsageTab));
00018     memset(pParser->OffsetTab,0,sizeof(pParser->OffsetTab));
00019     memset(&pParser->Data,0,sizeof(pParser->Data));
00020 }
00021     
00022 static void ResetLocalState(HIDParser* pParser)
00023 {
00024     pParser->UsageSize=0;
00025     memset(pParser->UsageTab,0,sizeof(pParser->UsageTab));
00026 }
00027     
00028 u8* GetReportOffset(HIDParser* pParser, 
00029                         const u8 ReportID, 
00030                         const u8 ReportType)
00031  {
00032    u8 Pos=0;
00033    while(Pos<MAX_REPORT && pParser->OffsetTab[Pos][0]!=0)
00034    {
00035      if(pParser->OffsetTab[Pos][0]==ReportID 
00036        && pParser->OffsetTab[Pos][1]==ReportType)
00037        return &pParser->OffsetTab[Pos][2];
00038      Pos++;
00039    }
00040    if(Pos<MAX_REPORT)
00041    {
00042      /* Increment Report count */
00043      pParser->nReport++;
00044      pParser->OffsetTab[Pos][0]=ReportID;
00045      pParser->OffsetTab[Pos][1]=ReportType;
00046      pParser->OffsetTab[Pos][2]=0;
00047      return &pParser->OffsetTab[Pos][2];
00048    }
00049    return NULL;
00050  }    
00051     
00052     
00053 long FormatValue(long Value, char Size)
00054  {
00055    if(Size==1) 
00056      Value=(long)(char)Value;
00057    else if(Size==2) 
00058      Value=(long)(short)Value;
00059    return Value;
00060  }
00061 
00062  int HIDParse(HIDParser* pParser, HIDData* pData)
00063  {
00064    int Found=0;
00065  
00066    while(!Found && pParser->Pos<pParser->ReportDescSize)
00067    {
00068      /* Get new pParser->Item if current pParser->Count is empty */
00069      if(pParser->Count==0)
00070      {
00071        pParser->Item=pParser->ReportDesc[pParser->Pos++];
00072        pParser->Value=0;
00073 
00074        memcpy(&pParser->Value, &pParser->ReportDesc[pParser->Pos], ItemSize[pParser->Item & SIZE_MASK]);
00075 
00076        /* Pos on next item */
00077        pParser->Pos+=ItemSize[pParser->Item & SIZE_MASK];
00078      }
00079  
00080      switch(pParser->Item & ITEM_MASK)
00081      {
00082        case ITEM_UPAGE :
00083        {
00084          /* Copy UPage in Usage stack */
00085          pParser->UPage=(u8)pParser->Value;
00086          break;
00087        }
00088        case ITEM_USAGE :
00089        {
00090          /* Copy global or local UPage if any, in Usage stack */
00091           if((pParser->Item & SIZE_MASK)>2)
00092           pParser->UsageTab[pParser->UsageSize].UPage=(u8)(pParser->Value>>16);
00093          else
00094           pParser->UsageTab[pParser->UsageSize].UPage=pParser->UPage;
00095  
00096          /* Copy Usage in Usage stack */
00097          pParser->UsageTab[pParser->UsageSize].Usage=(u8)(pParser->Value & 0xFFFF);
00098  
00099          /* Increment Usage stack size */
00100          pParser->UsageSize++;
00101  
00102          break;
00103        }
00104        case ITEM_COLLECTION :
00105        {
00106          /* Get UPage/Usage from UsageTab and store them in pParser->Data.Path */
00107          pParser->Data.Path.Node[pParser->Data.Path.Size].UPage=pParser->UsageTab[0].UPage;
00108          pParser->Data.Path.Node[pParser->Data.Path.Size].Usage=pParser->UsageTab[0].Usage;
00109          pParser->Data.Path.Size++;
00110        
00111          /* Unstack UPage/Usage from UsageTab (never remove the last) */
00112          if(pParser->UsageSize>0)
00113          {
00114            u8 ii=0;
00115            while(ii<pParser->UsageSize)
00116            {
00117              pParser->UsageTab[ii].Usage=pParser->UsageTab[ii+1].Usage;
00118              pParser->UsageTab[ii].UPage=pParser->UsageTab[ii+1].UPage;
00119             ii++;
00120            }
00121            /* Remove Usage */
00122            pParser->UsageSize--;
00123          }
00124 
00125          /* Get Index if any */
00126          if(pParser->Value>=0x80)
00127          {
00128            pParser->Data.Path.Node[pParser->Data.Path.Size].UPage=0xFF;
00129            pParser->Data.Path.Node[pParser->Data.Path.Size].Usage=pParser->Value & 0x7F;
00130            pParser->Data.Path.Size++;
00131        }
00132    ResetLocalState(pParser);
00133       break;
00134        }
00135      case ITEM_END_COLLECTION :
00136        {
00137          pParser->Data.Path.Size--;
00138          /* Remove Index if any */
00139          if(pParser->Data.Path.Node[pParser->Data.Path.Size].UPage==0xFF)
00140            pParser->Data.Path.Size--;
00141    ResetLocalState(pParser);
00142          break;
00143        }
00144        case ITEM_FEATURE :
00145        case ITEM_INPUT :
00146        case ITEM_OUTPUT :
00147        {
00148          /* An object was found */
00149          Found=1;
00150  
00151          /* Increment object count */
00152          pParser->nObject++;
00153 
00154      /* Get new pParser->Count from global value */
00155       if(pParser->Count==0)
00156      {
00157         pParser->Count=pParser->ReportCount;
00158        }
00159 
00160     /* Get UPage/Usage from UsageTab and store them in pParser->Data.Path */
00161         pParser->Data.Path.Node[pParser->Data.Path.Size].UPage=pParser->UsageTab[0].UPage;
00162          pParser->Data.Path.Node[pParser->Data.Path.Size].Usage=pParser->UsageTab[0].Usage;
00163          pParser->Data.Path.Size++;
00164 
00165          /* Unstack UPage/Usage from UsageTab (never remove the last) */
00166          if(pParser->UsageSize>0)
00167          {
00168            u8 ii=0;
00169            while(ii<pParser->UsageSize)
00170            {
00171              pParser->UsageTab[ii].UPage=pParser->UsageTab[ii+1].UPage;
00172              pParser->UsageTab[ii].Usage=pParser->UsageTab[ii+1].Usage;
00173              ii++;
00174            }
00175            /* Remove Usage */
00176            pParser->UsageSize--;
00177          }
00178  
00179          /* Copy data type */
00180          pParser->Data.Type=(u8)(pParser->Item & ITEM_MASK);
00181  
00182          /* Copy data attribute */
00183         pParser->Data.Attribute=(u8)pParser->Value;
00184  
00185          /* Store offset */
00186          pParser->Data.Offset=*GetReportOffset(pParser, pParser->Data.ReportID, (u8)(pParser->Item & ITEM_MASK));
00187      
00188          /* Get Object in pData */
00189          /* -------------------------------------------------------------------------- */
00190          memcpy(pData, &pParser->Data, sizeof(HIDData));
00191          /* -------------------------------------------------------------------------- */
00192  
00193          /* Increment Report Offset */
00194          *GetReportOffset(pParser, pParser->Data.ReportID, (u8)(pParser->Item & ITEM_MASK)) += pParser->Data.Size;
00195  
00196          /* Remove path last node */
00197          pParser->Data.Path.Size--;
00198  
00199          /* Decrement count */
00200          pParser->Count--;
00201   if (pParser->Count == 0) {
00202     ResetLocalState(pParser);
00203    }
00204         break;
00205        }
00206        case ITEM_REP_ID :
00207        {
00208         pParser->Data.ReportID=(u8)pParser->Value;
00209         break;
00210        }
00211        case ITEM_REP_SIZE :
00212        {
00213          pParser->Data.Size=(u8)pParser->Value;
00214          break;
00215        }
00216        case ITEM_REP_COUNT :
00217        {
00218         pParser->ReportCount=(u8)pParser->Value;
00219          break;
00220        }
00221        case ITEM_UNIT_EXP :
00222        {
00223          pParser->Data.UnitExp=(char)pParser->Value;
00224    // Convert 4 bits signed value to 8 bits signed value
00225    if (pParser->Data.UnitExp > 7)
00226      pParser->Data.UnitExp|=0xF0;
00227          break;
00228      }
00229        case ITEM_UNIT :
00230       {
00231         pParser->Data.Unit=pParser->Value;
00232          break;
00233        }
00234        case ITEM_LOG_MIN :
00235        {
00236          pParser->Data.LogMin=FormatValue(pParser->Value, ItemSize[pParser->Item & SIZE_MASK]);
00237          break;
00238        }
00239        case ITEM_LOG_MAX :
00240        {
00241          pParser->Data.LogMax=FormatValue(pParser->Value, ItemSize[pParser->Item & SIZE_MASK]);
00242          break;
00243        }
00244        case ITEM_PHY_MIN :
00245        {
00246         pParser->Data.PhyMin=FormatValue(pParser->Value, ItemSize[pParser->Item & SIZE_MASK]);
00247          break;
00248        }
00249        case ITEM_PHY_MAX :
00250        {
00251          pParser->Data.PhyMax=FormatValue(pParser->Value, ItemSize[pParser->Item & SIZE_MASK]);
00252          break;
00253        }
00254        case ITEM_LONG :
00255        {
00256    /* can't handle long items, but should at least skip them */
00257    pParser->Pos+=(u8)(pParser->Value & 0xff);
00258        }
00259     }
00260    } /* while(!Found && pParser->Pos<pParser->ReportDescSize) */
00261  
00262 /*   ERROR(pParser->Data.Path.Size>=PATH_SIZE);
00263    ERROR(pParser->ReportDescSize>=REPORT_DSC_SIZE);
00264    ERROR(pParser->UsageSize>=USAGE_TAB_SIZE);
00265    ERROR(pParser->Data.ReportID>=MAX_REPORT);
00266  */
00267    return Found;
00268  }
00269  
00270  int FindObject(HIDParser* pParser, HIDData* pData)
00271  {
00272    HIDData FoundData;
00273    ResetParser(pParser);
00274    while(HIDParse(pParser, &FoundData))
00275    {
00276      if(pData->Path.Size>0 && 
00277        FoundData.Type==pData->Type &&
00278        memcmp(FoundData.Path.Node, pData->Path.Node, (pData->Path.Size)*sizeof(HIDNode))==0)
00279      {
00280        memcpy(pData, &FoundData, sizeof(HIDData));
00281        return 1;
00282      }
00283      /* Found by ReportID/Offset */
00284      else if(FoundData.ReportID==pData->ReportID && 
00285        FoundData.Type==pData->Type &&
00286        FoundData.Offset==pData->Offset)
00287      {
00288        memcpy(pData, &FoundData, sizeof(HIDData));
00289        return 1;
00290      }
00291    }
00292    return 0;
00293  }
00294  
00295  void GetValue(const u8* Buf, HIDData* pData)
00296  {
00297    int Bit=pData->Offset+8; /* First byte of report indicate report ID */
00298    int Weight=0;
00299    pData->Value=0;
00300  
00301   while(Weight<pData->Size)
00302    {
00303      int State=Buf[Bit>>3]&(1<<(Bit%8));
00304      if(State)
00305     {
00306        pData->Value+=(1<<Weight);
00307      }
00308      Weight++;
00309     Bit++;
00310    }
00311  /*  if(pData->Value > pData->LogMax)
00312      pData->Value=FormatValue(pData->Value, (uchar)((pData->Size-1)/8+1));
00313  */
00314    if (pData->Value > pData->LogMax)
00315      pData->Value |= ~pData->LogMax;
00316  }
00317  
00318  void SetValue(const HIDData* pData, u8* Buf)
00319  {
00320   int Bit=pData->Offset+8; /* First byte of report indicate report ID */
00321   int Weight=0;
00322  
00323    while(Weight<pData->Size)
00324    {
00325      int State=pData->Value & (1<<Weight);
00326      
00327      if(Bit%8==0)
00328        Buf[Bit/8]=0;
00329  
00330      if(State)
00331      {
00332       Buf[Bit/8]+=(1<<(Weight%8));
00333      }
00334      Weight++;
00335      Bit++;
00336    }
00337  }
00338 
00339 
00340 
00341 
00342 
00343 
00344 
00345