These are the examples provided for [[/users/frank26080115/libraries/LPC1700CMSIS_Lib/]] Note, the entire "program" is not compilable!

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mscuser.c Source File

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 }