These are the examples provided for [[/users/frank26080115/libraries/LPC1700CMSIS_Lib/]] Note, the entire "program" is not compilable!
mscuser.c
00001 /*---------------------------------------------------------------------------- 00002 * U S B - K e r n e l 00003 *---------------------------------------------------------------------------- 00004 * Name: MSCUSER.C 00005 * Purpose: Mass Storage Class Custom User Module 00006 * Version: V1.10 00007 *---------------------------------------------------------------------------- 00008 * This software is supplied "AS IS" without any warranties, express, 00009 * implied or statutory, including but not limited to the implied 00010 * warranties of fitness for purpose, satisfactory quality and 00011 * noninfringement. Keil extends you a royalty-free right to reproduce 00012 * and distribute executable files created using this software for use 00013 * on NXP Semiconductors LPC family microcontroller devices only. Nothing 00014 * else gives you the right to use this software. 00015 * 00016 * Copyright (c) 2005-2009 Keil Software. 00017 *---------------------------------------------------------------------------*/ 00018 00019 #include "LPC17xx.h" 00020 00021 #include "lpc_types.h" 00022 00023 #include "usb.h" 00024 #include "msc.h" 00025 #include "usbcfg.h" 00026 #include "usbhw.h" 00027 #include "usbcore.h" 00028 #include "mscuser.h" 00029 00030 #include "memory.h" 00031 00032 00033 uint8_t Memory[MSC_MemorySize]; /* MSC RAM */ 00034 00035 uint32_t MemOK; /* Memory OK */ 00036 00037 uint32_t Offset; /* R/W Offset */ 00038 uint32_t Length; /* R/W Length */ 00039 00040 uint8_t BulkStage; /* Bulk Stage */ 00041 00042 uint8_t BulkBuf[MSC_MAX_PACKET]; /* Bulk In/Out Buffer */ 00043 uint8_t BulkLen; /* Bulk In/Out Length */ 00044 00045 MSC_CBW CBW; /* Command Block Wrapper */ 00046 MSC_CSW CSW; /* Command Status Wrapper */ 00047 00048 00049 /* 00050 * MSC Mass Storage Reset Request Callback 00051 * Called automatically on Mass Storage Reset Request 00052 * Parameters: None (global SetupPacket and EP0Buf) 00053 * Return Value: TRUE - Success, FALSE - Error 00054 */ 00055 00056 uint32_t MSC_Reset (void) { 00057 00058 BulkStage = MSC_BS_CBW; 00059 return (TRUE); 00060 } 00061 00062 00063 /* 00064 * MSC Get Max LUN Request Callback 00065 * Called automatically on Get Max LUN Request 00066 * Parameters: None (global SetupPacket and EP0Buf) 00067 * Return Value: TRUE - Success, FALSE - Error 00068 */ 00069 00070 uint32_t MSC_GetMaxLUN (void) { 00071 00072 EP0Buf[0] = 0; /* No LUN associated with this device */ 00073 return (TRUE); 00074 } 00075 00076 00077 /* 00078 * MSC Memory Read Callback 00079 * Called automatically on Memory Read Event 00080 * Parameters: None (global variables) 00081 * Return Value: None 00082 */ 00083 00084 void MSC_MemoryRead (void) { 00085 uint32_t n; 00086 00087 if (Length > MSC_MAX_PACKET) { 00088 n = MSC_MAX_PACKET; 00089 } else { 00090 n = Length; 00091 } 00092 00093 if ((Offset + n) > MSC_MemorySize) { 00094 n = MSC_MemorySize - Offset; 00095 BulkStage = MSC_BS_DATA_IN_LAST_STALL; 00096 } 00097 00098 USB_WriteEP(MSC_EP_IN, &Memory[Offset], n); 00099 Offset += n; 00100 Length -= n; 00101 00102 CSW.dDataResidue -= n; 00103 00104 if (Length == 0) { 00105 BulkStage = MSC_BS_DATA_IN_LAST; 00106 } 00107 00108 if (BulkStage != MSC_BS_DATA_IN) { 00109 CSW.bStatus = CSW_CMD_PASSED; 00110 } 00111 } 00112 00113 00114 /* 00115 * MSC Memory Write Callback 00116 * Called automatically on Memory Write Event 00117 * Parameters: None (global variables) 00118 * Return Value: None 00119 */ 00120 00121 void MSC_MemoryWrite (void) { 00122 uint32_t n; 00123 00124 if ((Offset + BulkLen) > MSC_MemorySize) { 00125 BulkLen = MSC_MemorySize - Offset; 00126 BulkStage = MSC_BS_CSW; 00127 USB_SetStallEP(MSC_EP_OUT); 00128 } 00129 00130 for (n = 0; n < BulkLen; n++) { 00131 Memory[Offset + n] = BulkBuf[n]; 00132 } 00133 00134 Offset += BulkLen; 00135 Length -= BulkLen; 00136 00137 CSW.dDataResidue -= BulkLen; 00138 00139 if ((Length == 0) || (BulkStage == MSC_BS_CSW)) { 00140 CSW.bStatus = CSW_CMD_PASSED; 00141 MSC_SetCSW(); 00142 } 00143 } 00144 00145 00146 /* 00147 * MSC Memory Verify Callback 00148 * Called automatically on Memory Verify Event 00149 * Parameters: None (global variables) 00150 * Return Value: None 00151 */ 00152 00153 void MSC_MemoryVerify (void) { 00154 uint32_t n; 00155 00156 if ((Offset + BulkLen) > MSC_MemorySize) { 00157 BulkLen = MSC_MemorySize - Offset; 00158 BulkStage = MSC_BS_CSW; 00159 USB_SetStallEP(MSC_EP_OUT); 00160 } 00161 00162 for (n = 0; n < BulkLen; n++) { 00163 if (Memory[Offset + n] != BulkBuf[n]) { 00164 MemOK = FALSE; 00165 break; 00166 } 00167 } 00168 00169 Offset += BulkLen; 00170 Length -= BulkLen; 00171 00172 CSW.dDataResidue -= BulkLen; 00173 00174 if ((Length == 0) || (BulkStage == MSC_BS_CSW)) { 00175 CSW.bStatus = (MemOK) ? CSW_CMD_PASSED : CSW_CMD_FAILED; 00176 MSC_SetCSW(); 00177 } 00178 } 00179 00180 00181 /* 00182 * MSC SCSI Read/Write Setup Callback 00183 * Parameters: None (global variables) 00184 * Return Value: TRUE - Success, FALSE - Error 00185 */ 00186 00187 uint32_t MSC_RWSetup (void) { 00188 uint32_t n; 00189 00190 /* Logical Block Address of First Block */ 00191 n = (CBW.CB[2] << 24) | 00192 (CBW.CB[3] << 16) | 00193 (CBW.CB[4] << 8) | 00194 (CBW.CB[5] << 0); 00195 00196 Offset = n * MSC_BlockSize; 00197 00198 /* Number of Blocks to transfer */ 00199 n = (CBW.CB[7] << 8) | 00200 (CBW.CB[8] << 0); 00201 00202 Length = n * MSC_BlockSize; 00203 00204 if (CBW.dDataLength != Length) { 00205 USB_SetStallEP(MSC_EP_IN); 00206 USB_SetStallEP(MSC_EP_OUT); 00207 CSW.bStatus = CSW_PHASE_ERROR; 00208 MSC_SetCSW(); 00209 return (FALSE); 00210 } 00211 00212 return (TRUE); 00213 } 00214 00215 00216 /* 00217 * Check Data IN Format 00218 * Parameters: None (global variables) 00219 * Return Value: TRUE - Success, FALSE - Error 00220 */ 00221 00222 uint32_t DataInFormat (void) { 00223 00224 if (CBW.dDataLength == 0) { 00225 CSW.bStatus = CSW_PHASE_ERROR; 00226 MSC_SetCSW(); 00227 return (FALSE); 00228 } 00229 if ((CBW.bmFlags & 0x80) == 0) { 00230 USB_SetStallEP(MSC_EP_OUT); 00231 CSW.bStatus = CSW_PHASE_ERROR; 00232 MSC_SetCSW(); 00233 return (FALSE); 00234 } 00235 return (TRUE); 00236 } 00237 00238 00239 /* 00240 * Perform Data IN Transfer 00241 * Parameters: None (global variables) 00242 * Return Value: TRUE - Success, FALSE - Error 00243 */ 00244 00245 void DataInTransfer (void) { 00246 00247 if (BulkLen > CBW.dDataLength) { 00248 BulkLen = CBW.dDataLength; 00249 } 00250 00251 USB_WriteEP(MSC_EP_IN, BulkBuf, BulkLen); 00252 BulkStage = MSC_BS_DATA_IN_LAST; 00253 00254 CSW.dDataResidue -= BulkLen; 00255 CSW.bStatus = CSW_CMD_PASSED; 00256 } 00257 00258 00259 /* 00260 * MSC SCSI Test Unit Ready Callback 00261 * Parameters: None (global variables) 00262 * Return Value: None 00263 */ 00264 00265 void MSC_TestUnitReady (void) { 00266 00267 if (CBW.dDataLength != 0) { 00268 if ((CBW.bmFlags & 0x80) != 0) { 00269 USB_SetStallEP(MSC_EP_IN); 00270 } else { 00271 USB_SetStallEP(MSC_EP_OUT); 00272 } 00273 } 00274 00275 CSW.bStatus = CSW_CMD_PASSED; 00276 MSC_SetCSW(); 00277 } 00278 00279 00280 /* 00281 * MSC SCSI Request Sense Callback 00282 * Parameters: None (global variables) 00283 * Return Value: None 00284 */ 00285 00286 void MSC_RequestSense (void) { 00287 00288 if (!DataInFormat()) return; 00289 00290 BulkBuf[ 0] = 0x70; /* Response Code */ 00291 BulkBuf[ 1] = 0x00; 00292 BulkBuf[ 2] = 0x02; /* Sense Key */ 00293 BulkBuf[ 3] = 0x00; 00294 BulkBuf[ 4] = 0x00; 00295 BulkBuf[ 5] = 0x00; 00296 BulkBuf[ 6] = 0x00; 00297 BulkBuf[ 7] = 0x0A; /* Additional Length */ 00298 BulkBuf[ 8] = 0x00; 00299 BulkBuf[ 9] = 0x00; 00300 BulkBuf[10] = 0x00; 00301 BulkBuf[11] = 0x00; 00302 BulkBuf[12] = 0x30; /* ASC */ 00303 BulkBuf[13] = 0x01; /* ASCQ */ 00304 BulkBuf[14] = 0x00; 00305 BulkBuf[15] = 0x00; 00306 BulkBuf[16] = 0x00; 00307 BulkBuf[17] = 0x00; 00308 00309 BulkLen = 18; 00310 DataInTransfer(); 00311 } 00312 00313 00314 /* 00315 * MSC SCSI Inquiry Callback 00316 * Parameters: None (global variables) 00317 * Return Value: None 00318 */ 00319 00320 void MSC_Inquiry (void) { 00321 00322 if (!DataInFormat()) return; 00323 00324 BulkBuf[ 0] = 0x00; /* Direct Access Device */ 00325 BulkBuf[ 1] = 0x80; /* RMB = 1: Removable Medium */ 00326 BulkBuf[ 2] = 0x00; /* Version: No conformance claim to standard */ 00327 BulkBuf[ 3] = 0x01; 00328 00329 BulkBuf[ 4] = 36-4; /* Additional Length */ 00330 BulkBuf[ 5] = 0x80; /* SCCS = 1: Storage Controller Component */ 00331 BulkBuf[ 6] = 0x00; 00332 BulkBuf[ 7] = 0x00; 00333 00334 BulkBuf[ 8] = 'K'; /* Vendor Identification */ 00335 BulkBuf[ 9] = 'e'; 00336 BulkBuf[10] = 'i'; 00337 BulkBuf[11] = 'l'; 00338 BulkBuf[12] = ' '; 00339 BulkBuf[13] = ' '; 00340 BulkBuf[14] = ' '; 00341 BulkBuf[15] = ' '; 00342 00343 BulkBuf[16] = 'L'; /* Product Identification */ 00344 BulkBuf[17] = 'P'; 00345 BulkBuf[18] = 'C'; 00346 BulkBuf[19] = '1'; 00347 BulkBuf[20] = '7'; 00348 BulkBuf[21] = 'x'; 00349 BulkBuf[22] = 'x'; 00350 BulkBuf[23] = ' '; 00351 BulkBuf[24] = 'D'; 00352 BulkBuf[25] = 'i'; 00353 BulkBuf[26] = 's'; 00354 BulkBuf[27] = 'k'; 00355 BulkBuf[28] = ' '; 00356 BulkBuf[29] = ' '; 00357 BulkBuf[30] = ' '; 00358 BulkBuf[31] = ' '; 00359 00360 BulkBuf[32] = '1'; /* Product Revision Level */ 00361 BulkBuf[33] = '.'; 00362 BulkBuf[34] = '0'; 00363 BulkBuf[35] = ' '; 00364 00365 BulkLen = 36; 00366 DataInTransfer(); 00367 } 00368 00369 00370 /* 00371 * MSC SCSI Mode Sense (6-Byte) Callback 00372 * Parameters: None (global variables) 00373 * Return Value: None 00374 */ 00375 00376 void MSC_ModeSense6 (void) { 00377 00378 if (!DataInFormat()) return; 00379 00380 BulkBuf[ 0] = 0x03; 00381 BulkBuf[ 1] = 0x00; 00382 BulkBuf[ 2] = 0x00; 00383 BulkBuf[ 3] = 0x00; 00384 00385 BulkLen = 4; 00386 DataInTransfer(); 00387 } 00388 00389 00390 /* 00391 * MSC SCSI Mode Sense (10-Byte) Callback 00392 * Parameters: None (global variables) 00393 * Return Value: None 00394 */ 00395 00396 void MSC_ModeSense10 (void) { 00397 00398 if (!DataInFormat()) return; 00399 00400 BulkBuf[ 0] = 0x00; 00401 BulkBuf[ 1] = 0x06; 00402 BulkBuf[ 2] = 0x00; 00403 BulkBuf[ 3] = 0x00; 00404 BulkBuf[ 4] = 0x00; 00405 BulkBuf[ 5] = 0x00; 00406 BulkBuf[ 6] = 0x00; 00407 BulkBuf[ 7] = 0x00; 00408 00409 BulkLen = 8; 00410 DataInTransfer(); 00411 } 00412 00413 00414 /* 00415 * MSC SCSI Read Capacity Callback 00416 * Parameters: None (global variables) 00417 * Return Value: None 00418 */ 00419 00420 void MSC_ReadCapacity (void) { 00421 00422 if (!DataInFormat()) return; 00423 00424 /* Last Logical Block */ 00425 BulkBuf[ 0] = ((MSC_BlockCount - 1) >> 24) & 0xFF; 00426 BulkBuf[ 1] = ((MSC_BlockCount - 1) >> 16) & 0xFF; 00427 BulkBuf[ 2] = ((MSC_BlockCount - 1) >> 8) & 0xFF; 00428 BulkBuf[ 3] = ((MSC_BlockCount - 1) >> 0) & 0xFF; 00429 00430 /* Block Length */ 00431 BulkBuf[ 4] = (MSC_BlockSize >> 24) & 0xFF; 00432 BulkBuf[ 5] = (MSC_BlockSize >> 16) & 0xFF; 00433 BulkBuf[ 6] = (MSC_BlockSize >> 8) & 0xFF; 00434 BulkBuf[ 7] = (MSC_BlockSize >> 0) & 0xFF; 00435 00436 BulkLen = 8; 00437 DataInTransfer(); 00438 } 00439 00440 00441 /* 00442 * MSC SCSI Read Format Capacity Callback 00443 * Parameters: None (global variables) 00444 * Return Value: None 00445 */ 00446 00447 void MSC_ReadFormatCapacity (void) { 00448 00449 if (!DataInFormat()) return; 00450 00451 BulkBuf[ 0] = 0x00; 00452 BulkBuf[ 1] = 0x00; 00453 BulkBuf[ 2] = 0x00; 00454 BulkBuf[ 3] = 0x08; /* Capacity List Length */ 00455 00456 /* Block Count */ 00457 BulkBuf[ 4] = (MSC_BlockCount >> 24) & 0xFF; 00458 BulkBuf[ 5] = (MSC_BlockCount >> 16) & 0xFF; 00459 BulkBuf[ 6] = (MSC_BlockCount >> 8) & 0xFF; 00460 BulkBuf[ 7] = (MSC_BlockCount >> 0) & 0xFF; 00461 00462 /* Block Length */ 00463 BulkBuf[ 8] = 0x02; /* Descriptor Code: Formatted Media */ 00464 BulkBuf[ 9] = (MSC_BlockSize >> 16) & 0xFF; 00465 BulkBuf[10] = (MSC_BlockSize >> 8) & 0xFF; 00466 BulkBuf[11] = (MSC_BlockSize >> 0) & 0xFF; 00467 00468 BulkLen = 12; 00469 DataInTransfer(); 00470 } 00471 00472 00473 /* 00474 * MSC Get Command Block Wrapper Callback 00475 * Parameters: None (global variables) 00476 * Return Value: None 00477 */ 00478 00479 void MSC_GetCBW (void) { 00480 uint32_t n; 00481 00482 for (n = 0; n < BulkLen; n++) { 00483 *((uint8_t *)&CBW + n) = BulkBuf[n]; 00484 } 00485 if ((BulkLen == sizeof(CBW)) && (CBW.dSignature == MSC_CBW_Signature)) { 00486 /* Valid CBW */ 00487 CSW.dTag = CBW.dTag; 00488 CSW.dDataResidue = CBW.dDataLength; 00489 if ((CBW.bLUN != 0) || (CBW.bCBLength < 1) || CBW.bCBLength > 16) { 00490 fail: CSW.bStatus = CSW_CMD_FAILED; 00491 MSC_SetCSW(); 00492 } else { 00493 switch (CBW.CB[0]) { 00494 case SCSI_TEST_UNIT_READY: 00495 MSC_TestUnitReady(); 00496 break; 00497 case SCSI_REQUEST_SENSE: 00498 MSC_RequestSense(); 00499 break; 00500 case SCSI_FORMAT_UNIT: 00501 goto fail; 00502 case SCSI_INQUIRY: 00503 MSC_Inquiry(); 00504 break; 00505 case SCSI_START_STOP_UNIT: 00506 goto fail; 00507 case SCSI_MEDIA_REMOVAL: 00508 goto fail; 00509 case SCSI_MODE_SELECT6: 00510 goto fail; 00511 case SCSI_MODE_SENSE6: 00512 MSC_ModeSense6(); 00513 break; 00514 case SCSI_MODE_SELECT10: 00515 goto fail; 00516 case SCSI_MODE_SENSE10: 00517 MSC_ModeSense10(); 00518 break; 00519 case SCSI_READ_FORMAT_CAPACITIES: 00520 MSC_ReadFormatCapacity(); 00521 break; 00522 case SCSI_READ_CAPACITY: 00523 MSC_ReadCapacity(); 00524 break; 00525 case SCSI_READ10: 00526 if (MSC_RWSetup()) { 00527 if ((CBW.bmFlags & 0x80) != 0) { 00528 BulkStage = MSC_BS_DATA_IN; 00529 MSC_MemoryRead(); 00530 } else { 00531 USB_SetStallEP(MSC_EP_OUT); 00532 CSW.bStatus = CSW_PHASE_ERROR; 00533 MSC_SetCSW(); 00534 } 00535 } 00536 break; 00537 case SCSI_WRITE10: 00538 if (MSC_RWSetup()) { 00539 if ((CBW.bmFlags & 0x80) == 0) { 00540 BulkStage = MSC_BS_DATA_OUT; 00541 } else { 00542 USB_SetStallEP(MSC_EP_IN); 00543 CSW.bStatus = CSW_PHASE_ERROR; 00544 MSC_SetCSW(); 00545 } 00546 } 00547 break; 00548 case SCSI_VERIFY10: 00549 if (MSC_RWSetup()) { 00550 if ((CBW.bmFlags & 0x80) == 0) { 00551 BulkStage = MSC_BS_DATA_OUT; 00552 MemOK = TRUE; 00553 } else { 00554 USB_SetStallEP(MSC_EP_IN); 00555 CSW.bStatus = CSW_PHASE_ERROR; 00556 MSC_SetCSW(); 00557 } 00558 } 00559 break; 00560 default: 00561 goto fail; 00562 } 00563 } 00564 } else { 00565 /* Invalid CBW */ 00566 USB_SetStallEP(MSC_EP_IN); 00567 USB_SetStallEP(MSC_EP_OUT); 00568 BulkStage = MSC_BS_ERROR; 00569 } 00570 } 00571 00572 00573 /* 00574 * MSC Set Command Status Wrapper Callback 00575 * Parameters: None (global variables) 00576 * Return Value: None 00577 */ 00578 00579 void MSC_SetCSW (void) { 00580 00581 CSW.dSignature = MSC_CSW_Signature; 00582 USB_WriteEP(MSC_EP_IN, (uint8_t *)&CSW, sizeof(CSW)); 00583 BulkStage = MSC_BS_CSW; 00584 } 00585 00586 00587 /* 00588 * MSC Bulk In Callback 00589 * Parameters: None (global variables) 00590 * Return Value: None 00591 */ 00592 00593 void MSC_BulkIn (void) { 00594 00595 switch (BulkStage) { 00596 case MSC_BS_DATA_IN: 00597 switch (CBW.CB[0]) { 00598 case SCSI_READ10: 00599 MSC_MemoryRead(); 00600 break; 00601 } 00602 break; 00603 case MSC_BS_DATA_IN_LAST: 00604 MSC_SetCSW(); 00605 break; 00606 case MSC_BS_DATA_IN_LAST_STALL: 00607 USB_SetStallEP(MSC_EP_IN); 00608 MSC_SetCSW(); 00609 break; 00610 case MSC_BS_CSW: 00611 BulkStage = MSC_BS_CBW; 00612 break; 00613 } 00614 } 00615 00616 00617 /* 00618 * MSC Bulk Out Callback 00619 * Parameters: None (global variables) 00620 * Return Value: None 00621 */ 00622 00623 void MSC_BulkOut (void) { 00624 00625 BulkLen = USB_ReadEP(MSC_EP_OUT, BulkBuf); 00626 switch (BulkStage) { 00627 case MSC_BS_CBW: 00628 MSC_GetCBW(); 00629 break; 00630 case MSC_BS_DATA_OUT: 00631 switch (CBW.CB[0]) { 00632 case SCSI_WRITE10: 00633 MSC_MemoryWrite(); 00634 break; 00635 case SCSI_VERIFY10: 00636 MSC_MemoryVerify(); 00637 break; 00638 } 00639 break; 00640 default: 00641 USB_SetStallEP(MSC_EP_OUT); 00642 CSW.bStatus = CSW_PHASE_ERROR; 00643 MSC_SetCSW(); 00644 break; 00645 } 00646 }
Generated on Tue Jul 12 2022 17:28:09 by 1.7.2