Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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
Generated on Thu Jul 14 2022 02:50:59 by
1.7.2