00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00046 #include "type.h"
00047 #include "debug.h"
00048
00049 #include "usbstruct.h"
00050 #include "usbapi.h"
00051 #include "usbhw_lpc.h"
00052
00053 #define MAX_DESC_HANDLERS 4
00056
00057 #define DESC_bLength 0
00058 #define DESC_bDescriptorType 1
00060
00061 #define CONF_DESC_wTotalLength 2
00062 #define CONF_DESC_bConfigurationValue 5
00063 #define CONF_DESC_bmAttributes 7
00065
00066 #define INTF_DESC_bAlternateSetting 3
00068
00069 #define ENDP_DESC_bEndpointAddress 2
00070 #define ENDP_DESC_wMaxPacketSize 4
00074 static U8 bConfiguration = 0;
00075
00076 static TFnHandleRequest *pfnHandleCustomReq = NULL;
00078 static const U8 *pabDescrip = NULL;
00079
00080
00087 void USBRegisterDescriptors(const U8 *pabDescriptors)
00088 {
00089 pabDescrip = pabDescriptors;
00090 }
00091
00092
00104 BOOL USBGetDescriptor(U16 wTypeIndex, U16 wLangID, int *piLen, U8 **ppbData)
00105 {
00106 U8 bType, bIndex;
00107 U8 *pab;
00108 int iCurIndex;
00109
00110 ASSERT(pabDescrip != NULL);
00111
00112 bType = GET_DESC_TYPE(wTypeIndex);
00113 bIndex = GET_DESC_INDEX(wTypeIndex);
00114
00115 pab = (U8 *)pabDescrip;
00116 iCurIndex = 0;
00117
00118 while (pab[DESC_bLength] != 0) {
00119 if (pab[DESC_bDescriptorType] == bType) {
00120 if (iCurIndex == bIndex) {
00121
00122 *ppbData = pab;
00123
00124 if (bType == DESC_CONFIGURATION) {
00125
00126 *piLen = (pab[CONF_DESC_wTotalLength]) |
00127 (pab[CONF_DESC_wTotalLength + 1] << 8);
00128 }
00129 else {
00130
00131 *piLen = pab[DESC_bLength];
00132 }
00133 return TRUE;
00134 }
00135 iCurIndex++;
00136 }
00137
00138 pab += pab[DESC_bLength];
00139 }
00140
00141 DBG("Desc %x not found!\n", wTypeIndex);
00142 return FALSE;
00143 }
00144
00145
00158 static BOOL USBSetConfiguration(U8 bConfigIndex, U8 bAltSetting)
00159 {
00160 U8 *pab;
00161 U8 bCurConfig, bCurAltSetting;
00162 U8 bEP;
00163 U16 wMaxPktSize;
00164
00165 ASSERT(pabDescrip != NULL);
00166
00167 if (bConfigIndex == 0) {
00168
00169 USBHwConfigDevice(FALSE);
00170 }
00171 else {
00172
00173 pab = (U8 *)pabDescrip;
00174 bCurConfig = 0xFF;
00175 bCurAltSetting = 0xFF;
00176
00177 while (pab[DESC_bLength] != 0) {
00178
00179 switch (pab[DESC_bDescriptorType]) {
00180
00181 case DESC_CONFIGURATION:
00182
00183 bCurConfig = pab[CONF_DESC_bConfigurationValue];
00184 break;
00185
00186 case DESC_INTERFACE:
00187
00188 bCurAltSetting = pab[INTF_DESC_bAlternateSetting];
00189 break;
00190
00191 case DESC_ENDPOINT:
00192 if ((bCurConfig == bConfigIndex) &&
00193 (bCurAltSetting == bAltSetting)) {
00194
00195 bEP = pab[ENDP_DESC_bEndpointAddress];
00196 wMaxPktSize = (pab[ENDP_DESC_wMaxPacketSize]) |
00197 (pab[ENDP_DESC_wMaxPacketSize + 1] << 8);
00198
00199 USBHwEPConfig(bEP, wMaxPktSize);
00200 }
00201 break;
00202
00203 default:
00204 break;
00205 }
00206
00207 pab += pab[DESC_bLength];
00208 }
00209
00210
00211 USBHwConfigDevice(TRUE);
00212 }
00213
00214 return TRUE;
00215 }
00216
00217
00227 static BOOL HandleStdDeviceReq(TSetupPacket *pSetup, int *piLen, U8 **ppbData)
00228 {
00229 U8 *pbData = *ppbData;
00230
00231 switch (pSetup->bRequest) {
00232
00233 case REQ_GET_STATUS:
00234
00235
00236 pbData[0] = 0;
00237 pbData[1] = 0;
00238 *piLen = 2;
00239 break;
00240
00241 case REQ_SET_ADDRESS:
00242 USBHwSetAddress(pSetup->wValue);
00243 break;
00244
00245 case REQ_GET_DESCRIPTOR:
00246 DBG("D%x", pSetup->wValue);
00247 return USBGetDescriptor(pSetup->wValue, pSetup->wIndex, piLen, ppbData);
00248
00249 case REQ_GET_CONFIGURATION:
00250
00251 pbData[0] = bConfiguration;
00252 *piLen = 1;
00253 break;
00254
00255 case REQ_SET_CONFIGURATION:
00256 if (!USBSetConfiguration(pSetup->wValue & 0xFF, 0)) {
00257 DBG("USBSetConfiguration failed!\n");
00258 return FALSE;
00259 }
00260
00261 bConfiguration = pSetup->wValue & 0xFF;
00262 break;
00263
00264 case REQ_CLEAR_FEATURE:
00265 case REQ_SET_FEATURE:
00266 if (pSetup->wValue == FEA_REMOTE_WAKEUP) {
00267
00268 }
00269 if (pSetup->wValue == FEA_TEST_MODE) {
00270
00271 }
00272 return FALSE;
00273
00274 case REQ_SET_DESCRIPTOR:
00275 DBG("Device req %d not implemented\n", pSetup->bRequest);
00276 return FALSE;
00277
00278 default:
00279 DBG("Illegal device req %d\n", pSetup->bRequest);
00280 return FALSE;
00281 }
00282
00283 return TRUE;
00284 }
00285
00286
00296 static BOOL HandleStdInterfaceReq(TSetupPacket *pSetup, int *piLen, U8 **ppbData)
00297 {
00298 U8 *pbData = *ppbData;
00299
00300 switch (pSetup->bRequest) {
00301
00302 case REQ_GET_STATUS:
00303
00304 pbData[0] = 0;
00305 pbData[1] = 0;
00306 *piLen = 2;
00307 break;
00308
00309 case REQ_CLEAR_FEATURE:
00310 case REQ_SET_FEATURE:
00311
00312 return FALSE;
00313
00314 case REQ_GET_INTERFACE:
00315
00316 pbData[0] = 0;
00317 *piLen = 1;
00318 break;
00319
00320 case REQ_SET_INTERFACE:
00321
00322 if (pSetup->wValue != 0) {
00323 return FALSE;
00324 }
00325 *piLen = 0;
00326 break;
00327
00328 default:
00329 DBG("Illegal interface req %d\n", pSetup->bRequest);
00330 return FALSE;
00331 }
00332
00333 return TRUE;
00334 }
00335
00336
00346 static BOOL HandleStdEndPointReq(TSetupPacket *pSetup, int *piLen, U8 **ppbData)
00347 {
00348 U8 *pbData = *ppbData;
00349
00350 switch (pSetup->bRequest) {
00351 case REQ_GET_STATUS:
00352
00353 pbData[0] = (USBHwEPGetStatus(pSetup->wIndex) & EP_STATUS_STALLED) ? 1 : 0;
00354 pbData[1] = 0;
00355 *piLen = 2;
00356 break;
00357
00358 case REQ_CLEAR_FEATURE:
00359 if (pSetup->wValue == FEA_ENDPOINT_HALT) {
00360
00361 USBHwEPStall(pSetup->wIndex, FALSE);
00362 break;
00363 }
00364
00365 return FALSE;
00366
00367 case REQ_SET_FEATURE:
00368 if (pSetup->wValue == FEA_ENDPOINT_HALT) {
00369
00370 USBHwEPStall(pSetup->wIndex, TRUE);
00371 break;
00372 }
00373
00374 return FALSE;
00375
00376 case REQ_SYNCH_FRAME:
00377 DBG("EP req %d not implemented\n", pSetup->bRequest);
00378 return FALSE;
00379
00380 default:
00381 DBG("Illegal EP req %d\n", pSetup->bRequest);
00382 return FALSE;
00383 }
00384
00385 return TRUE;
00386 }
00387
00388
00400 BOOL USBHandleStandardRequest(TSetupPacket *pSetup, int *piLen, U8 **ppbData)
00401 {
00402
00403 if ((pfnHandleCustomReq != NULL) && pfnHandleCustomReq(pSetup, piLen, ppbData)) {
00404 return TRUE;
00405 }
00406
00407 switch (REQTYPE_GET_RECIP(pSetup->bmRequestType)) {
00408 case REQTYPE_RECIP_DEVICE: return HandleStdDeviceReq(pSetup, piLen, ppbData);
00409 case REQTYPE_RECIP_INTERFACE: return HandleStdInterfaceReq(pSetup, piLen, ppbData);
00410 case REQTYPE_RECIP_ENDPOINT: return HandleStdEndPointReq(pSetup, piLen, ppbData);
00411 default: return FALSE;
00412 }
00413 }
00414
00415
00429 void USBRegisterCustomReqHandler(TFnHandleRequest *pfnHandler)
00430 {
00431 pfnHandleCustomReq = pfnHandler;
00432 }
00433