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
00051 #include "type.h"
00052 #include "debug.h"
00053
00054 #include "usbstruct.h"
00055 #include "usbapi.h"
00056
00057
00058
00059 #define MAX_CONTROL_SIZE 128
00060 #define MAX_REQ_HANDLERS 4
00062 static TSetupPacket Setup;
00064 static U8 *pbData;
00065 static int iResidue;
00066 static int iLen;
00069 static TFnHandleRequest *apfnReqHandlers[4] = {NULL, NULL, NULL, NULL};
00070
00071 static U8 *apbDataStore[4] = {NULL, NULL, NULL, NULL};
00072
00087 static BOOL _HandleRequest(TSetupPacket *pSetup, int *piLen, U8 **ppbData)
00088 {
00089 TFnHandleRequest *pfnHandler;
00090 int iType;
00091
00092 iType = REQTYPE_GET_TYPE(pSetup->bmRequestType);
00093 pfnHandler = apfnReqHandlers[iType];
00094 if (pfnHandler == NULL) {
00095 DBG("No handler for reqtype %d\n", iType);
00096 return FALSE;
00097 }
00098
00099 return pfnHandler(pSetup, piLen, ppbData);
00100 }
00101
00102
00108 static void StallControlPipe(U8 bEPStat)
00109 {
00110 U8 *pb;
00111 int i;
00112
00113 USBHwEPStall(0x80, TRUE);
00114
00115
00116 DBG("STALL on [");
00117 pb = (U8 *)&Setup;
00118 for (i = 0; i < 8; i++) {
00119 DBG(" %02x", *pb++);
00120 }
00121 DBG("] stat=%x\n", bEPStat);
00122 }
00123
00124
00128 static void DataIn(void)
00129 {
00130 int iChunk;
00131
00132 iChunk = MIN(MAX_PACKET_SIZE0, iResidue);
00133 USBHwEPWrite(0x80, pbData, iChunk);
00134 pbData += iChunk;
00135 iResidue -= iChunk;
00136 }
00137
00138
00145 void USBHandleControlTransfer(U8 bEP, U8 bEPStat)
00146 {
00147 int iChunk, iType;
00148
00149 if (bEP == 0x00) {
00150
00151 if (bEPStat & EP_STATUS_SETUP) {
00152
00153 USBHwEPRead(0x00, (U8 *)&Setup, sizeof(Setup));
00154 DBG("S%x", Setup.bRequest);
00155
00156
00157 iType = REQTYPE_GET_TYPE(Setup.bmRequestType);
00158 pbData = apbDataStore[iType];
00159 iResidue = Setup.wLength;
00160 iLen = Setup.wLength;
00161
00162 if ((Setup.wLength == 0) ||
00163 (REQTYPE_GET_DIR(Setup.bmRequestType) == REQTYPE_DIR_TO_HOST)) {
00164
00165 if (!_HandleRequest(&Setup, &iLen, &pbData)) {
00166 DBG("_HandleRequest1 failed\n");
00167 StallControlPipe(bEPStat);
00168 return;
00169 }
00170
00171 iResidue = MIN(iLen, Setup.wLength);
00172
00173 DataIn();
00174 }
00175 }
00176 else {
00177 if (iResidue > 0) {
00178
00179 iChunk = USBHwEPRead(0x00, pbData, iResidue);
00180 if (iChunk < 0) {
00181 StallControlPipe(bEPStat);
00182 return;
00183 }
00184 pbData += iChunk;
00185 iResidue -= iChunk;
00186 if (iResidue == 0) {
00187
00188 iType = REQTYPE_GET_TYPE(Setup.bmRequestType);
00189 pbData = apbDataStore[iType];
00190 if (!_HandleRequest(&Setup, &iLen, &pbData)) {
00191 DBG("_HandleRequest2 failed\n");
00192 StallControlPipe(bEPStat);
00193 return;
00194 }
00195
00196 DataIn();
00197 }
00198 }
00199 else {
00200
00201 iChunk = USBHwEPRead(0x00, NULL, 0);
00202 DBG(iChunk > 0 ? "?" : "");
00203 }
00204 }
00205 }
00206 else if (bEP == 0x80) {
00207
00208
00209 DataIn();
00210 }
00211 else {
00212 ASSERT(FALSE);
00213 }
00214 }
00215
00216
00224 void USBRegisterRequestHandler(int iType, TFnHandleRequest *pfnHandler, U8 *pbDataStore)
00225 {
00226 ASSERT(iType >= 0);
00227 ASSERT(iType < 4);
00228 apfnReqHandlers[iType] = pfnHandler;
00229 apbDataStore[iType] = pbDataStore;
00230 }
00231