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

Committer:
Sergio
Date:
Mon Sep 13 12:40:05 2010 +0000
Revision:
0:e1e03118b8fe

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sergio 0:e1e03118b8fe 1
Sergio 0:e1e03118b8fe 2
Sergio 0:e1e03118b8fe 3 #include "mbed.h"
Sergio 0:e1e03118b8fe 4 #include "HID.h"
Sergio 0:e1e03118b8fe 5
Sergio 0:e1e03118b8fe 6
Sergio 0:e1e03118b8fe 7
Sergio 0:e1e03118b8fe 8 const char ItemSize[4]={0,1,2,4};
Sergio 0:e1e03118b8fe 9
Sergio 0:e1e03118b8fe 10 void ResetParser(HIDParser* pParser)
Sergio 0:e1e03118b8fe 11 {
Sergio 0:e1e03118b8fe 12 pParser->Pos=0;
Sergio 0:e1e03118b8fe 13 pParser->Count=0;
Sergio 0:e1e03118b8fe 14 pParser->nObject=0;
Sergio 0:e1e03118b8fe 15 pParser->nReport=0;
Sergio 0:e1e03118b8fe 16 pParser->UsageSize=0;
Sergio 0:e1e03118b8fe 17 memset(pParser->UsageTab,0,sizeof(pParser->UsageTab));
Sergio 0:e1e03118b8fe 18 memset(pParser->OffsetTab,0,sizeof(pParser->OffsetTab));
Sergio 0:e1e03118b8fe 19 memset(&pParser->Data,0,sizeof(pParser->Data));
Sergio 0:e1e03118b8fe 20 }
Sergio 0:e1e03118b8fe 21
Sergio 0:e1e03118b8fe 22 static void ResetLocalState(HIDParser* pParser)
Sergio 0:e1e03118b8fe 23 {
Sergio 0:e1e03118b8fe 24 pParser->UsageSize=0;
Sergio 0:e1e03118b8fe 25 memset(pParser->UsageTab,0,sizeof(pParser->UsageTab));
Sergio 0:e1e03118b8fe 26 }
Sergio 0:e1e03118b8fe 27
Sergio 0:e1e03118b8fe 28 u8* GetReportOffset(HIDParser* pParser,
Sergio 0:e1e03118b8fe 29 const u8 ReportID,
Sergio 0:e1e03118b8fe 30 const u8 ReportType)
Sergio 0:e1e03118b8fe 31 {
Sergio 0:e1e03118b8fe 32 u8 Pos=0;
Sergio 0:e1e03118b8fe 33 while(Pos<MAX_REPORT && pParser->OffsetTab[Pos][0]!=0)
Sergio 0:e1e03118b8fe 34 {
Sergio 0:e1e03118b8fe 35 if(pParser->OffsetTab[Pos][0]==ReportID
Sergio 0:e1e03118b8fe 36 && pParser->OffsetTab[Pos][1]==ReportType)
Sergio 0:e1e03118b8fe 37 return &pParser->OffsetTab[Pos][2];
Sergio 0:e1e03118b8fe 38 Pos++;
Sergio 0:e1e03118b8fe 39 }
Sergio 0:e1e03118b8fe 40 if(Pos<MAX_REPORT)
Sergio 0:e1e03118b8fe 41 {
Sergio 0:e1e03118b8fe 42 /* Increment Report count */
Sergio 0:e1e03118b8fe 43 pParser->nReport++;
Sergio 0:e1e03118b8fe 44 pParser->OffsetTab[Pos][0]=ReportID;
Sergio 0:e1e03118b8fe 45 pParser->OffsetTab[Pos][1]=ReportType;
Sergio 0:e1e03118b8fe 46 pParser->OffsetTab[Pos][2]=0;
Sergio 0:e1e03118b8fe 47 return &pParser->OffsetTab[Pos][2];
Sergio 0:e1e03118b8fe 48 }
Sergio 0:e1e03118b8fe 49 return NULL;
Sergio 0:e1e03118b8fe 50 }
Sergio 0:e1e03118b8fe 51
Sergio 0:e1e03118b8fe 52
Sergio 0:e1e03118b8fe 53 long FormatValue(long Value, char Size)
Sergio 0:e1e03118b8fe 54 {
Sergio 0:e1e03118b8fe 55 if(Size==1)
Sergio 0:e1e03118b8fe 56 Value=(long)(char)Value;
Sergio 0:e1e03118b8fe 57 else if(Size==2)
Sergio 0:e1e03118b8fe 58 Value=(long)(short)Value;
Sergio 0:e1e03118b8fe 59 return Value;
Sergio 0:e1e03118b8fe 60 }
Sergio 0:e1e03118b8fe 61
Sergio 0:e1e03118b8fe 62 int HIDParse(HIDParser* pParser, HIDData* pData)
Sergio 0:e1e03118b8fe 63 {
Sergio 0:e1e03118b8fe 64 int Found=0;
Sergio 0:e1e03118b8fe 65
Sergio 0:e1e03118b8fe 66 while(!Found && pParser->Pos<pParser->ReportDescSize)
Sergio 0:e1e03118b8fe 67 {
Sergio 0:e1e03118b8fe 68 /* Get new pParser->Item if current pParser->Count is empty */
Sergio 0:e1e03118b8fe 69 if(pParser->Count==0)
Sergio 0:e1e03118b8fe 70 {
Sergio 0:e1e03118b8fe 71 pParser->Item=pParser->ReportDesc[pParser->Pos++];
Sergio 0:e1e03118b8fe 72 pParser->Value=0;
Sergio 0:e1e03118b8fe 73
Sergio 0:e1e03118b8fe 74 memcpy(&pParser->Value, &pParser->ReportDesc[pParser->Pos], ItemSize[pParser->Item & SIZE_MASK]);
Sergio 0:e1e03118b8fe 75
Sergio 0:e1e03118b8fe 76 /* Pos on next item */
Sergio 0:e1e03118b8fe 77 pParser->Pos+=ItemSize[pParser->Item & SIZE_MASK];
Sergio 0:e1e03118b8fe 78 }
Sergio 0:e1e03118b8fe 79
Sergio 0:e1e03118b8fe 80 switch(pParser->Item & ITEM_MASK)
Sergio 0:e1e03118b8fe 81 {
Sergio 0:e1e03118b8fe 82 case ITEM_UPAGE :
Sergio 0:e1e03118b8fe 83 {
Sergio 0:e1e03118b8fe 84 /* Copy UPage in Usage stack */
Sergio 0:e1e03118b8fe 85 pParser->UPage=(u8)pParser->Value;
Sergio 0:e1e03118b8fe 86 break;
Sergio 0:e1e03118b8fe 87 }
Sergio 0:e1e03118b8fe 88 case ITEM_USAGE :
Sergio 0:e1e03118b8fe 89 {
Sergio 0:e1e03118b8fe 90 /* Copy global or local UPage if any, in Usage stack */
Sergio 0:e1e03118b8fe 91 if((pParser->Item & SIZE_MASK)>2)
Sergio 0:e1e03118b8fe 92 pParser->UsageTab[pParser->UsageSize].UPage=(u8)(pParser->Value>>16);
Sergio 0:e1e03118b8fe 93 else
Sergio 0:e1e03118b8fe 94 pParser->UsageTab[pParser->UsageSize].UPage=pParser->UPage;
Sergio 0:e1e03118b8fe 95
Sergio 0:e1e03118b8fe 96 /* Copy Usage in Usage stack */
Sergio 0:e1e03118b8fe 97 pParser->UsageTab[pParser->UsageSize].Usage=(u8)(pParser->Value & 0xFFFF);
Sergio 0:e1e03118b8fe 98
Sergio 0:e1e03118b8fe 99 /* Increment Usage stack size */
Sergio 0:e1e03118b8fe 100 pParser->UsageSize++;
Sergio 0:e1e03118b8fe 101
Sergio 0:e1e03118b8fe 102 break;
Sergio 0:e1e03118b8fe 103 }
Sergio 0:e1e03118b8fe 104 case ITEM_COLLECTION :
Sergio 0:e1e03118b8fe 105 {
Sergio 0:e1e03118b8fe 106 /* Get UPage/Usage from UsageTab and store them in pParser->Data.Path */
Sergio 0:e1e03118b8fe 107 pParser->Data.Path.Node[pParser->Data.Path.Size].UPage=pParser->UsageTab[0].UPage;
Sergio 0:e1e03118b8fe 108 pParser->Data.Path.Node[pParser->Data.Path.Size].Usage=pParser->UsageTab[0].Usage;
Sergio 0:e1e03118b8fe 109 pParser->Data.Path.Size++;
Sergio 0:e1e03118b8fe 110
Sergio 0:e1e03118b8fe 111 /* Unstack UPage/Usage from UsageTab (never remove the last) */
Sergio 0:e1e03118b8fe 112 if(pParser->UsageSize>0)
Sergio 0:e1e03118b8fe 113 {
Sergio 0:e1e03118b8fe 114 u8 ii=0;
Sergio 0:e1e03118b8fe 115 while(ii<pParser->UsageSize)
Sergio 0:e1e03118b8fe 116 {
Sergio 0:e1e03118b8fe 117 pParser->UsageTab[ii].Usage=pParser->UsageTab[ii+1].Usage;
Sergio 0:e1e03118b8fe 118 pParser->UsageTab[ii].UPage=pParser->UsageTab[ii+1].UPage;
Sergio 0:e1e03118b8fe 119 ii++;
Sergio 0:e1e03118b8fe 120 }
Sergio 0:e1e03118b8fe 121 /* Remove Usage */
Sergio 0:e1e03118b8fe 122 pParser->UsageSize--;
Sergio 0:e1e03118b8fe 123 }
Sergio 0:e1e03118b8fe 124
Sergio 0:e1e03118b8fe 125 /* Get Index if any */
Sergio 0:e1e03118b8fe 126 if(pParser->Value>=0x80)
Sergio 0:e1e03118b8fe 127 {
Sergio 0:e1e03118b8fe 128 pParser->Data.Path.Node[pParser->Data.Path.Size].UPage=0xFF;
Sergio 0:e1e03118b8fe 129 pParser->Data.Path.Node[pParser->Data.Path.Size].Usage=pParser->Value & 0x7F;
Sergio 0:e1e03118b8fe 130 pParser->Data.Path.Size++;
Sergio 0:e1e03118b8fe 131 }
Sergio 0:e1e03118b8fe 132 ResetLocalState(pParser);
Sergio 0:e1e03118b8fe 133 break;
Sergio 0:e1e03118b8fe 134 }
Sergio 0:e1e03118b8fe 135 case ITEM_END_COLLECTION :
Sergio 0:e1e03118b8fe 136 {
Sergio 0:e1e03118b8fe 137 pParser->Data.Path.Size--;
Sergio 0:e1e03118b8fe 138 /* Remove Index if any */
Sergio 0:e1e03118b8fe 139 if(pParser->Data.Path.Node[pParser->Data.Path.Size].UPage==0xFF)
Sergio 0:e1e03118b8fe 140 pParser->Data.Path.Size--;
Sergio 0:e1e03118b8fe 141 ResetLocalState(pParser);
Sergio 0:e1e03118b8fe 142 break;
Sergio 0:e1e03118b8fe 143 }
Sergio 0:e1e03118b8fe 144 case ITEM_FEATURE :
Sergio 0:e1e03118b8fe 145 case ITEM_INPUT :
Sergio 0:e1e03118b8fe 146 case ITEM_OUTPUT :
Sergio 0:e1e03118b8fe 147 {
Sergio 0:e1e03118b8fe 148 /* An object was found */
Sergio 0:e1e03118b8fe 149 Found=1;
Sergio 0:e1e03118b8fe 150
Sergio 0:e1e03118b8fe 151 /* Increment object count */
Sergio 0:e1e03118b8fe 152 pParser->nObject++;
Sergio 0:e1e03118b8fe 153
Sergio 0:e1e03118b8fe 154 /* Get new pParser->Count from global value */
Sergio 0:e1e03118b8fe 155 if(pParser->Count==0)
Sergio 0:e1e03118b8fe 156 {
Sergio 0:e1e03118b8fe 157 pParser->Count=pParser->ReportCount;
Sergio 0:e1e03118b8fe 158 }
Sergio 0:e1e03118b8fe 159
Sergio 0:e1e03118b8fe 160 /* Get UPage/Usage from UsageTab and store them in pParser->Data.Path */
Sergio 0:e1e03118b8fe 161 pParser->Data.Path.Node[pParser->Data.Path.Size].UPage=pParser->UsageTab[0].UPage;
Sergio 0:e1e03118b8fe 162 pParser->Data.Path.Node[pParser->Data.Path.Size].Usage=pParser->UsageTab[0].Usage;
Sergio 0:e1e03118b8fe 163 pParser->Data.Path.Size++;
Sergio 0:e1e03118b8fe 164
Sergio 0:e1e03118b8fe 165 /* Unstack UPage/Usage from UsageTab (never remove the last) */
Sergio 0:e1e03118b8fe 166 if(pParser->UsageSize>0)
Sergio 0:e1e03118b8fe 167 {
Sergio 0:e1e03118b8fe 168 u8 ii=0;
Sergio 0:e1e03118b8fe 169 while(ii<pParser->UsageSize)
Sergio 0:e1e03118b8fe 170 {
Sergio 0:e1e03118b8fe 171 pParser->UsageTab[ii].UPage=pParser->UsageTab[ii+1].UPage;
Sergio 0:e1e03118b8fe 172 pParser->UsageTab[ii].Usage=pParser->UsageTab[ii+1].Usage;
Sergio 0:e1e03118b8fe 173 ii++;
Sergio 0:e1e03118b8fe 174 }
Sergio 0:e1e03118b8fe 175 /* Remove Usage */
Sergio 0:e1e03118b8fe 176 pParser->UsageSize--;
Sergio 0:e1e03118b8fe 177 }
Sergio 0:e1e03118b8fe 178
Sergio 0:e1e03118b8fe 179 /* Copy data type */
Sergio 0:e1e03118b8fe 180 pParser->Data.Type=(u8)(pParser->Item & ITEM_MASK);
Sergio 0:e1e03118b8fe 181
Sergio 0:e1e03118b8fe 182 /* Copy data attribute */
Sergio 0:e1e03118b8fe 183 pParser->Data.Attribute=(u8)pParser->Value;
Sergio 0:e1e03118b8fe 184
Sergio 0:e1e03118b8fe 185 /* Store offset */
Sergio 0:e1e03118b8fe 186 pParser->Data.Offset=*GetReportOffset(pParser, pParser->Data.ReportID, (u8)(pParser->Item & ITEM_MASK));
Sergio 0:e1e03118b8fe 187
Sergio 0:e1e03118b8fe 188 /* Get Object in pData */
Sergio 0:e1e03118b8fe 189 /* -------------------------------------------------------------------------- */
Sergio 0:e1e03118b8fe 190 memcpy(pData, &pParser->Data, sizeof(HIDData));
Sergio 0:e1e03118b8fe 191 /* -------------------------------------------------------------------------- */
Sergio 0:e1e03118b8fe 192
Sergio 0:e1e03118b8fe 193 /* Increment Report Offset */
Sergio 0:e1e03118b8fe 194 *GetReportOffset(pParser, pParser->Data.ReportID, (u8)(pParser->Item & ITEM_MASK)) += pParser->Data.Size;
Sergio 0:e1e03118b8fe 195
Sergio 0:e1e03118b8fe 196 /* Remove path last node */
Sergio 0:e1e03118b8fe 197 pParser->Data.Path.Size--;
Sergio 0:e1e03118b8fe 198
Sergio 0:e1e03118b8fe 199 /* Decrement count */
Sergio 0:e1e03118b8fe 200 pParser->Count--;
Sergio 0:e1e03118b8fe 201 if (pParser->Count == 0) {
Sergio 0:e1e03118b8fe 202 ResetLocalState(pParser);
Sergio 0:e1e03118b8fe 203 }
Sergio 0:e1e03118b8fe 204 break;
Sergio 0:e1e03118b8fe 205 }
Sergio 0:e1e03118b8fe 206 case ITEM_REP_ID :
Sergio 0:e1e03118b8fe 207 {
Sergio 0:e1e03118b8fe 208 pParser->Data.ReportID=(u8)pParser->Value;
Sergio 0:e1e03118b8fe 209 break;
Sergio 0:e1e03118b8fe 210 }
Sergio 0:e1e03118b8fe 211 case ITEM_REP_SIZE :
Sergio 0:e1e03118b8fe 212 {
Sergio 0:e1e03118b8fe 213 pParser->Data.Size=(u8)pParser->Value;
Sergio 0:e1e03118b8fe 214 break;
Sergio 0:e1e03118b8fe 215 }
Sergio 0:e1e03118b8fe 216 case ITEM_REP_COUNT :
Sergio 0:e1e03118b8fe 217 {
Sergio 0:e1e03118b8fe 218 pParser->ReportCount=(u8)pParser->Value;
Sergio 0:e1e03118b8fe 219 break;
Sergio 0:e1e03118b8fe 220 }
Sergio 0:e1e03118b8fe 221 case ITEM_UNIT_EXP :
Sergio 0:e1e03118b8fe 222 {
Sergio 0:e1e03118b8fe 223 pParser->Data.UnitExp=(char)pParser->Value;
Sergio 0:e1e03118b8fe 224 // Convert 4 bits signed value to 8 bits signed value
Sergio 0:e1e03118b8fe 225 if (pParser->Data.UnitExp > 7)
Sergio 0:e1e03118b8fe 226 pParser->Data.UnitExp|=0xF0;
Sergio 0:e1e03118b8fe 227 break;
Sergio 0:e1e03118b8fe 228 }
Sergio 0:e1e03118b8fe 229 case ITEM_UNIT :
Sergio 0:e1e03118b8fe 230 {
Sergio 0:e1e03118b8fe 231 pParser->Data.Unit=pParser->Value;
Sergio 0:e1e03118b8fe 232 break;
Sergio 0:e1e03118b8fe 233 }
Sergio 0:e1e03118b8fe 234 case ITEM_LOG_MIN :
Sergio 0:e1e03118b8fe 235 {
Sergio 0:e1e03118b8fe 236 pParser->Data.LogMin=FormatValue(pParser->Value, ItemSize[pParser->Item & SIZE_MASK]);
Sergio 0:e1e03118b8fe 237 break;
Sergio 0:e1e03118b8fe 238 }
Sergio 0:e1e03118b8fe 239 case ITEM_LOG_MAX :
Sergio 0:e1e03118b8fe 240 {
Sergio 0:e1e03118b8fe 241 pParser->Data.LogMax=FormatValue(pParser->Value, ItemSize[pParser->Item & SIZE_MASK]);
Sergio 0:e1e03118b8fe 242 break;
Sergio 0:e1e03118b8fe 243 }
Sergio 0:e1e03118b8fe 244 case ITEM_PHY_MIN :
Sergio 0:e1e03118b8fe 245 {
Sergio 0:e1e03118b8fe 246 pParser->Data.PhyMin=FormatValue(pParser->Value, ItemSize[pParser->Item & SIZE_MASK]);
Sergio 0:e1e03118b8fe 247 break;
Sergio 0:e1e03118b8fe 248 }
Sergio 0:e1e03118b8fe 249 case ITEM_PHY_MAX :
Sergio 0:e1e03118b8fe 250 {
Sergio 0:e1e03118b8fe 251 pParser->Data.PhyMax=FormatValue(pParser->Value, ItemSize[pParser->Item & SIZE_MASK]);
Sergio 0:e1e03118b8fe 252 break;
Sergio 0:e1e03118b8fe 253 }
Sergio 0:e1e03118b8fe 254 case ITEM_LONG :
Sergio 0:e1e03118b8fe 255 {
Sergio 0:e1e03118b8fe 256 /* can't handle long items, but should at least skip them */
Sergio 0:e1e03118b8fe 257 pParser->Pos+=(u8)(pParser->Value & 0xff);
Sergio 0:e1e03118b8fe 258 }
Sergio 0:e1e03118b8fe 259 }
Sergio 0:e1e03118b8fe 260 } /* while(!Found && pParser->Pos<pParser->ReportDescSize) */
Sergio 0:e1e03118b8fe 261
Sergio 0:e1e03118b8fe 262 /* ERROR(pParser->Data.Path.Size>=PATH_SIZE);
Sergio 0:e1e03118b8fe 263 ERROR(pParser->ReportDescSize>=REPORT_DSC_SIZE);
Sergio 0:e1e03118b8fe 264 ERROR(pParser->UsageSize>=USAGE_TAB_SIZE);
Sergio 0:e1e03118b8fe 265 ERROR(pParser->Data.ReportID>=MAX_REPORT);
Sergio 0:e1e03118b8fe 266 */
Sergio 0:e1e03118b8fe 267 return Found;
Sergio 0:e1e03118b8fe 268 }
Sergio 0:e1e03118b8fe 269
Sergio 0:e1e03118b8fe 270 int FindObject(HIDParser* pParser, HIDData* pData)
Sergio 0:e1e03118b8fe 271 {
Sergio 0:e1e03118b8fe 272 HIDData FoundData;
Sergio 0:e1e03118b8fe 273 ResetParser(pParser);
Sergio 0:e1e03118b8fe 274 while(HIDParse(pParser, &FoundData))
Sergio 0:e1e03118b8fe 275 {
Sergio 0:e1e03118b8fe 276 if(pData->Path.Size>0 &&
Sergio 0:e1e03118b8fe 277 FoundData.Type==pData->Type &&
Sergio 0:e1e03118b8fe 278 memcmp(FoundData.Path.Node, pData->Path.Node, (pData->Path.Size)*sizeof(HIDNode))==0)
Sergio 0:e1e03118b8fe 279 {
Sergio 0:e1e03118b8fe 280 memcpy(pData, &FoundData, sizeof(HIDData));
Sergio 0:e1e03118b8fe 281 return 1;
Sergio 0:e1e03118b8fe 282 }
Sergio 0:e1e03118b8fe 283 /* Found by ReportID/Offset */
Sergio 0:e1e03118b8fe 284 else if(FoundData.ReportID==pData->ReportID &&
Sergio 0:e1e03118b8fe 285 FoundData.Type==pData->Type &&
Sergio 0:e1e03118b8fe 286 FoundData.Offset==pData->Offset)
Sergio 0:e1e03118b8fe 287 {
Sergio 0:e1e03118b8fe 288 memcpy(pData, &FoundData, sizeof(HIDData));
Sergio 0:e1e03118b8fe 289 return 1;
Sergio 0:e1e03118b8fe 290 }
Sergio 0:e1e03118b8fe 291 }
Sergio 0:e1e03118b8fe 292 return 0;
Sergio 0:e1e03118b8fe 293 }
Sergio 0:e1e03118b8fe 294
Sergio 0:e1e03118b8fe 295 void GetValue(const u8* Buf, HIDData* pData)
Sergio 0:e1e03118b8fe 296 {
Sergio 0:e1e03118b8fe 297 int Bit=pData->Offset+8; /* First byte of report indicate report ID */
Sergio 0:e1e03118b8fe 298 int Weight=0;
Sergio 0:e1e03118b8fe 299 pData->Value=0;
Sergio 0:e1e03118b8fe 300
Sergio 0:e1e03118b8fe 301 while(Weight<pData->Size)
Sergio 0:e1e03118b8fe 302 {
Sergio 0:e1e03118b8fe 303 int State=Buf[Bit>>3]&(1<<(Bit%8));
Sergio 0:e1e03118b8fe 304 if(State)
Sergio 0:e1e03118b8fe 305 {
Sergio 0:e1e03118b8fe 306 pData->Value+=(1<<Weight);
Sergio 0:e1e03118b8fe 307 }
Sergio 0:e1e03118b8fe 308 Weight++;
Sergio 0:e1e03118b8fe 309 Bit++;
Sergio 0:e1e03118b8fe 310 }
Sergio 0:e1e03118b8fe 311 /* if(pData->Value > pData->LogMax)
Sergio 0:e1e03118b8fe 312 pData->Value=FormatValue(pData->Value, (uchar)((pData->Size-1)/8+1));
Sergio 0:e1e03118b8fe 313 */
Sergio 0:e1e03118b8fe 314 if (pData->Value > pData->LogMax)
Sergio 0:e1e03118b8fe 315 pData->Value |= ~pData->LogMax;
Sergio 0:e1e03118b8fe 316 }
Sergio 0:e1e03118b8fe 317
Sergio 0:e1e03118b8fe 318 void SetValue(const HIDData* pData, u8* Buf)
Sergio 0:e1e03118b8fe 319 {
Sergio 0:e1e03118b8fe 320 int Bit=pData->Offset+8; /* First byte of report indicate report ID */
Sergio 0:e1e03118b8fe 321 int Weight=0;
Sergio 0:e1e03118b8fe 322
Sergio 0:e1e03118b8fe 323 while(Weight<pData->Size)
Sergio 0:e1e03118b8fe 324 {
Sergio 0:e1e03118b8fe 325 int State=pData->Value & (1<<Weight);
Sergio 0:e1e03118b8fe 326
Sergio 0:e1e03118b8fe 327 if(Bit%8==0)
Sergio 0:e1e03118b8fe 328 Buf[Bit/8]=0;
Sergio 0:e1e03118b8fe 329
Sergio 0:e1e03118b8fe 330 if(State)
Sergio 0:e1e03118b8fe 331 {
Sergio 0:e1e03118b8fe 332 Buf[Bit/8]+=(1<<(Weight%8));
Sergio 0:e1e03118b8fe 333 }
Sergio 0:e1e03118b8fe 334 Weight++;
Sergio 0:e1e03118b8fe 335 Bit++;
Sergio 0:e1e03118b8fe 336 }
Sergio 0:e1e03118b8fe 337 }
Sergio 0:e1e03118b8fe 338
Sergio 0:e1e03118b8fe 339
Sergio 0:e1e03118b8fe 340
Sergio 0:e1e03118b8fe 341
Sergio 0:e1e03118b8fe 342
Sergio 0:e1e03118b8fe 343
Sergio 0:e1e03118b8fe 344
Sergio 0:e1e03118b8fe 345