This package contains a simple test of tests for various elements of the SmartBoard hardware, which is a simple baseboard designed for easy embedding. It is able to run both a semi-automatic test suite as well as allow interactive testing.
Dependencies: EthernetNetIf NTPClient_NetServices mbed
usbhost_ms.c
00001 /* 00002 ************************************************************************************************************** 00003 * NXP USB Host Stack 00004 * 00005 * (c) Copyright 2008, NXP SemiConductors 00006 * (c) Copyright 2008, OnChip Technologies LLC 00007 * All Rights Reserved 00008 * 00009 * www.nxp.com 00010 * www.onchiptech.com 00011 * 00012 * File : usbhost_ms.c 00013 * Programmer(s) : Ravikanth.P 00014 * Version : 00015 * 00016 ************************************************************************************************************** 00017 */ 00018 00019 /* 00020 ************************************************************************************************************** 00021 * INCLUDE HEADER FILES 00022 ************************************************************************************************************** 00023 */ 00024 00025 #include "usbhost_ms.h" 00026 00027 // Added DEBUG_X to eliminate annoying print statements 00028 // Copyright (c) 2011, David Smart 00029 00030 // Define to see additional details 00031 //#define DEBUG_X 00032 00033 /* 00034 ************************************************************************************************************** 00035 * GLOBAL VARIABLES 00036 ************************************************************************************************************** 00037 */ 00038 00039 USB_INT32U MS_BlkSize; 00040 00041 /* 00042 ************************************************************************************************************** 00043 * INITIALIZE MASS STORAGE INTERFACE 00044 * 00045 * Description: This function initializes the mass storage interface 00046 * 00047 * Arguments : None 00048 * 00049 * Returns : OK if Success 00050 * ERR_INVALID_BOOTSIG if Failed 00051 * 00052 ************************************************************************************************************** 00053 */ 00054 00055 USB_INT32S MS_Init (USB_INT32U *blkSize, USB_INT32U *numBlks, USB_INT08U *inquiryResult) 00056 { 00057 USB_INT08U retry; 00058 USB_INT32S rc; 00059 00060 MS_GetMaxLUN(); /* Get maximum logical unit number */ 00061 retry = 80; 00062 while(retry) { 00063 rc = MS_TestUnitReady(); /* Test whether the unit is ready */ 00064 if (rc == OK) { 00065 break; 00066 } 00067 MS_GetSenseInfo(); /* Get sense information */ 00068 retry--; 00069 } 00070 if (rc != OK) { 00071 PRINT_Err(rc); 00072 return (rc); 00073 } 00074 rc = MS_ReadCapacity(numBlks, blkSize); /* Read capacity of the disk */ 00075 MS_BlkSize = *blkSize; // Set global 00076 rc = MS_Inquire (inquiryResult); 00077 return (rc); 00078 } 00079 /* 00080 ************************************************************************************************************** 00081 * PARSE THE CONFIGURATION 00082 * 00083 * Description: This function is used to parse the configuration 00084 * 00085 * Arguments : None 00086 * 00087 * Returns : OK if Success 00088 * ERR_INVALID_BOOTSIG if Failed 00089 * 00090 ************************************************************************************************************** 00091 */ 00092 00093 USB_INT32S MS_ParseConfiguration (void) 00094 { 00095 volatile USB_INT08U *desc_ptr; 00096 USB_INT08U ms_int_found; 00097 00098 00099 desc_ptr = TDBuffer; 00100 ms_int_found = 0; 00101 00102 if (desc_ptr[1] != USB_DESCRIPTOR_TYPE_CONFIGURATION) { 00103 return (ERR_BAD_CONFIGURATION); 00104 } 00105 desc_ptr += desc_ptr[0]; 00106 00107 while (desc_ptr != TDBuffer + ReadLE16U(&TDBuffer[2])) { 00108 00109 switch (desc_ptr[1]) { 00110 00111 case USB_DESCRIPTOR_TYPE_INTERFACE: /* If it is an interface descriptor */ 00112 if (desc_ptr[5] == MASS_STORAGE_CLASS && /* check if the class is mass storage */ 00113 desc_ptr[6] == MASS_STORAGE_SUBCLASS_SCSI && /* check if the subclass is SCSI */ 00114 desc_ptr[7] == MASS_STORAGE_PROTOCOL_BO) { /* check if the protocol is Bulk only */ 00115 ms_int_found = 1; 00116 desc_ptr += desc_ptr[0]; /* Move to next descriptor start */ 00117 } 00118 break; 00119 00120 case USB_DESCRIPTOR_TYPE_ENDPOINT: /* If it is an endpoint descriptor */ 00121 if ((desc_ptr[3] & 0x03) == 0x02) { /* If it is Bulk endpoint */ 00122 if (desc_ptr[2] & 0x80) { /* If it is In endpoint */ 00123 EDBulkIn->Control = 1 | /* USB address */ 00124 ((desc_ptr[2] & 0x7F) << 7) | /* Endpoint address */ 00125 (2 << 11) | /* direction */ 00126 (ReadLE16U(&desc_ptr[4]) << 16); /* MaxPkt Size */ 00127 desc_ptr += desc_ptr[0]; /* Move to next descriptor start */ 00128 } else { /* If it is Out endpoint */ 00129 EDBulkOut->Control = 1 | /* USB address */ 00130 ((desc_ptr[2] & 0x7F) << 7) | /* Endpoint address */ 00131 (1 << 11) | /* direction */ 00132 (ReadLE16U(&desc_ptr[4]) << 16); /* MaxPkt Size */ 00133 desc_ptr += desc_ptr[0]; /* Move to next descriptor start */ 00134 } 00135 } else { /* If it is not bulk end point */ 00136 desc_ptr += desc_ptr[0]; /* Move to next descriptor start */ 00137 } 00138 break; 00139 00140 default: /* If the descriptor is neither interface nor endpoint */ 00141 desc_ptr += desc_ptr[0]; /* Move to next descriptor start */ 00142 break; 00143 } 00144 } 00145 if (ms_int_found) { 00146 #ifdef DEBUG_X 00147 PRINT_Log("Mass Storage device connected\n"); 00148 #endif 00149 return (OK); 00150 } else { 00151 #ifdef DEBUG_X 00152 PRINT_Log("Not a Mass Storage device\n"); 00153 #endif 00154 return (ERR_NO_MS_INTERFACE); 00155 } 00156 } 00157 00158 /* 00159 ************************************************************************************************************** 00160 * GET MAXIMUM LOGICAL UNIT 00161 * 00162 * Description: This function returns the maximum logical unit from the device 00163 * 00164 * Arguments : None 00165 * 00166 * Returns : OK if Success 00167 * ERR_INVALID_BOOTSIG if Failed 00168 * 00169 ************************************************************************************************************** 00170 */ 00171 00172 USB_INT32S MS_GetMaxLUN (void) 00173 { 00174 USB_INT32S rc; 00175 00176 00177 rc = Host_CtrlRecv(USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE, 00178 MS_GET_MAX_LUN_REQ, 00179 0, 00180 0, 00181 1, 00182 TDBuffer); 00183 return (rc); 00184 } 00185 00186 /* 00187 ************************************************************************************************************** 00188 * GET SENSE INFORMATION 00189 * 00190 * Description: This function is used to get sense information from the device 00191 * 00192 * Arguments : None 00193 * 00194 * Returns : OK if Success 00195 * ERROR if Failed 00196 * 00197 ************************************************************************************************************** 00198 */ 00199 00200 USB_INT32S MS_GetSenseInfo (void) 00201 { 00202 USB_INT32S rc; 00203 00204 00205 Fill_MSCommand(0, 0, 0, MS_DATA_DIR_IN, SCSI_CMD_REQUEST_SENSE, 6); 00206 rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE); 00207 if (rc == OK) { 00208 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, 18); 00209 if (rc == OK) { 00210 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE); 00211 if (rc == OK) { 00212 if (TDBuffer[12] != 0) { 00213 rc = ERR_MS_CMD_FAILED; 00214 } 00215 } 00216 } 00217 } 00218 return (rc); 00219 } 00220 00221 /* 00222 ************************************************************************************************************** 00223 * TEST UNIT READY 00224 * 00225 * Description: This function is used to test whether the unit is ready or not 00226 * 00227 * Arguments : None 00228 * 00229 * Returns : OK if Success 00230 * ERROR if Failed 00231 * 00232 ************************************************************************************************************** 00233 */ 00234 00235 USB_INT32S MS_TestUnitReady (void) 00236 { 00237 USB_INT32S rc; 00238 00239 00240 Fill_MSCommand(0, 0, 0, MS_DATA_DIR_NONE, SCSI_CMD_TEST_UNIT_READY, 6); 00241 rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE); 00242 if (rc == OK) { 00243 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE); 00244 if (rc == OK) { 00245 if (TDBuffer[12] != 0) { 00246 rc = ERR_MS_CMD_FAILED; 00247 } 00248 } 00249 } 00250 return (rc); 00251 } 00252 00253 /* 00254 ************************************************************************************************************** 00255 * READ CAPACITY 00256 * 00257 * Description: This function is used to read the capacity of the mass storage device 00258 * 00259 * Arguments : None 00260 * 00261 * Returns : OK if Success 00262 * ERROR if Failed 00263 * 00264 ************************************************************************************************************** 00265 */ 00266 00267 USB_INT32S MS_ReadCapacity (USB_INT32U *numBlks, USB_INT32U *blkSize) 00268 { 00269 USB_INT32S rc; 00270 00271 00272 Fill_MSCommand(0, 0, 0, MS_DATA_DIR_IN, SCSI_CMD_READ_CAPACITY, 10); 00273 rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE); 00274 if (rc == OK) { 00275 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, 8); 00276 if (rc == OK) { 00277 if (numBlks) 00278 *numBlks = ReadBE32U(&TDBuffer[0]); 00279 if (blkSize) 00280 *blkSize = ReadBE32U(&TDBuffer[4]); 00281 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE); 00282 if (rc == OK) { 00283 if (TDBuffer[12] != 0) { 00284 rc = ERR_MS_CMD_FAILED; 00285 } 00286 } 00287 } 00288 } 00289 return (rc); 00290 } 00291 00292 00293 00294 USB_INT32S MS_Inquire (USB_INT08U *response) 00295 { 00296 USB_INT32S rc; 00297 USB_INT32U i; 00298 00299 Fill_MSCommand(0, 0, 0, MS_DATA_DIR_IN, SCSI_CMD_INQUIRY, 6); 00300 rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE); 00301 if (rc == OK) { 00302 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, INQUIRY_LENGTH); 00303 if (rc == OK) { 00304 if (response) { 00305 for ( i = 0; i < INQUIRY_LENGTH; i++ ) 00306 *response++ = *TDBuffer++; 00307 #if 0 00308 MemCpy (response, TDBuffer, INQUIRY_LENGTH); 00309 StrNullTrailingSpace (response->vendorID, SCSI_INQUIRY_VENDORCHARS); 00310 StrNullTrailingSpace (response->productID, SCSI_INQUIRY_PRODUCTCHARS); 00311 StrNullTrailingSpace (response->productRev, SCSI_INQUIRY_REVCHARS); 00312 #endif 00313 } 00314 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE); 00315 if (rc == OK) { 00316 if (TDBuffer[12] != 0) { // bCSWStatus byte 00317 rc = ERR_MS_CMD_FAILED; 00318 } 00319 } 00320 } 00321 } 00322 return (rc); 00323 } 00324 00325 /* 00326 ************************************************************************************************************** 00327 * RECEIVE THE BULK DATA 00328 * 00329 * Description: This function is used to receive the bulk data 00330 * 00331 * Arguments : None 00332 * 00333 * Returns : OK if Success 00334 * ERR_INVALID_BOOTSIG if Failed 00335 * 00336 ************************************************************************************************************** 00337 */ 00338 00339 USB_INT32S MS_BulkRecv ( USB_INT32U block_number, 00340 USB_INT16U num_blocks, 00341 volatile USB_INT08U *user_buffer) 00342 { 00343 USB_INT32S rc; 00344 int i; 00345 volatile USB_INT08U *c = user_buffer; 00346 for (i=0;i<MS_BlkSize*num_blocks;i++) 00347 *c++ = 0; 00348 00349 00350 Fill_MSCommand(block_number, MS_BlkSize, num_blocks, MS_DATA_DIR_IN, SCSI_CMD_READ_10, 10); 00351 00352 rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE); 00353 if (rc == OK) { 00354 rc = Host_ProcessTD(EDBulkIn, TD_IN, user_buffer, MS_BlkSize * num_blocks); 00355 if (rc == OK) { 00356 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE); 00357 if (rc == OK) { 00358 if (TDBuffer[12] != 0) { 00359 rc = ERR_MS_CMD_FAILED; 00360 } 00361 } 00362 } 00363 } 00364 return (rc); 00365 } 00366 00367 /* 00368 ************************************************************************************************************** 00369 * SEND BULK DATA 00370 * 00371 * Description: This function is used to send the bulk data 00372 * 00373 * Arguments : None 00374 * 00375 * Returns : OK if Success 00376 * ERR_INVALID_BOOTSIG if Failed 00377 * 00378 ************************************************************************************************************** 00379 */ 00380 00381 USB_INT32S MS_BulkSend ( USB_INT32U block_number, 00382 USB_INT16U num_blocks, 00383 volatile USB_INT08U *user_buffer) 00384 { 00385 USB_INT32S rc; 00386 00387 00388 Fill_MSCommand(block_number, MS_BlkSize, num_blocks, MS_DATA_DIR_OUT, SCSI_CMD_WRITE_10, 10); 00389 00390 rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE); 00391 if (rc == OK) { 00392 rc = Host_ProcessTD(EDBulkOut, TD_OUT, user_buffer, MS_BlkSize * num_blocks); 00393 if (rc == OK) { 00394 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE); 00395 if (rc == OK) { 00396 if (TDBuffer[12] != 0) { 00397 rc = ERR_MS_CMD_FAILED; 00398 } 00399 } 00400 } 00401 } 00402 return (rc); 00403 } 00404 00405 /* 00406 ************************************************************************************************************** 00407 * FILL MASS STORAGE COMMAND 00408 * 00409 * Description: This function is used to fill the mass storage command 00410 * 00411 * Arguments : None 00412 * 00413 * Returns : OK if Success 00414 * ERR_INVALID_BOOTSIG if Failed 00415 * 00416 ************************************************************************************************************** 00417 */ 00418 00419 void Fill_MSCommand (USB_INT32U block_number, 00420 USB_INT32U block_size, 00421 USB_INT16U num_blocks, 00422 MS_DATA_DIR direction, 00423 USB_INT08U scsi_cmd, 00424 USB_INT08U scsi_cmd_len) 00425 { 00426 USB_INT32U data_len; 00427 static USB_INT32U tag_cnt = 0; 00428 USB_INT32U cnt; 00429 00430 00431 for (cnt = 0; cnt < CBW_SIZE; cnt++) { 00432 TDBuffer[cnt] = 0; 00433 } 00434 switch(scsi_cmd) { 00435 00436 case SCSI_CMD_TEST_UNIT_READY: 00437 data_len = 0; 00438 break; 00439 case SCSI_CMD_READ_CAPACITY: 00440 data_len = 8; 00441 break; 00442 case SCSI_CMD_REQUEST_SENSE: 00443 data_len = 18; 00444 break; 00445 case SCSI_CMD_INQUIRY: 00446 data_len = 36; 00447 break; 00448 default: 00449 data_len = block_size * num_blocks; 00450 break; 00451 } 00452 WriteLE32U(TDBuffer, CBW_SIGNATURE); 00453 WriteLE32U(&TDBuffer[4], tag_cnt); 00454 WriteLE32U(&TDBuffer[8], data_len); 00455 TDBuffer[12] = (direction == MS_DATA_DIR_NONE) ? 0 : direction; 00456 TDBuffer[14] = scsi_cmd_len; /* Length of the CBW */ 00457 TDBuffer[15] = scsi_cmd; 00458 if ((scsi_cmd == SCSI_CMD_REQUEST_SENSE) 00459 || (scsi_cmd == SCSI_CMD_INQUIRY)) { 00460 TDBuffer[19] = (USB_INT08U)data_len; 00461 } else { 00462 WriteBE32U(&TDBuffer[17], block_number); 00463 } 00464 WriteBE16U(&TDBuffer[22], num_blocks); 00465 }
Generated on Thu Jul 21 2022 00:25:24 by 1.7.2