RL-ARM mass storage sample and CD-ROM

Hi my friends!

I've used RL-ARM mass storage code from sample codes of KEIL 4.03 on AT91SAM7S256.
when I attach it to PC , the system recognizes it as a flash disk, correctly;

now I want to change it to apear as a CD-ROM in windows.

I want to know any changes in code.

can anyone help me?

thanks for your help!

Parents
  • Both of USB drive (stick) and CD/DVD drive are supported by USB Mass-Storage Class, Bulk-Only Transport. Therefore, there is no difference on the USB protocol layer.

    The differences lie in the SCSI command layer.
    1) PDT (Peripheral Device Type): 00h (Direct-Access device, eg. USB drive) --> 05h (CD/DVD)

    2) Sector (Block) size: 512 byte --> 2048 bytes

    3) Required SCSI command set
    - READ10 --> READ12
    - WRITE10 --> WRITE12 (for CD-R/DVD-R)
    - Start/Stop Uint (optional --> required)
    - Read TOC (Not Available --> required) - information of sections/tracks on the CD
    -- see "5.1 READ TOC" on usb_msc_boot_1.0.pdf for bootable CD
    www.usb.org/.../usb_msc_boot_1.0.pdf

    Lastly, as of the contents on the CD image, see these specs.

    ECMA-119 (ISO9660)
    www.ecma-international.org/.../Ecma-119.htm

    Joliet Specification
    pierrelib.pagesperso-orange.fr/.../joliet_spec_v1.html

    “El Torito” Bootable CD-ROM Format Specification
    bochs.sourceforge.net/.../el-torito.pdf.gz




    > I've used RL-ARM mass storage code from sample codes of KEIL 4.03 on AT91SAM7S256.

    Is this example?
    C:\Keil\ARM\Boards\Atmel\AT91SAM7S-EK\RL\USB\RTX_Memory

    It's the first time I look in this example. With quick look, it looks like almost same as NXP LPC examples, except for the hardware layer.

    1) PDT
    PDT is reported in the reply to INQUIRY command.

    mscuser.c
    
    void MSC_Inquiry (void) {
    
      if (!DataInFormat()) return;
    
      BulkBuf[ 0] = 0x00;          /* Direct Access Device */   <--- 0x05 (CD/DVD)
      ...
    

    2) Sector (Block) size
    The sector size is defined in the mscuser.h
    It is applied to READ CAPACITY and READ FORMAT CAPACITY command, automatically.

    mscuser.h
    
    /* Mass Storage Memory Layout */
    #define MSC_MemorySize  8192  // <---- tune this size for the total CD capacity
    #define MSC_BlockSize   512   // <---- 2048
    

    3) Required SCSI command set
    Add definitions for the extra SCSI commands

    msc.h
    
    /* SCSI Commands */
    ...
    #define SCSI_READ12                     0xA8
    #define SCSI_WRITE12                    0xAA
    #define SCSI_READ_TOC                   0x43
    

    SCSI command parser is modified, as follows,

    mscuser.c
    
    void MSC_GetCBW (void) {
       ...
       ...
          switch (CBW.CB[0]) {
            ...
            ...
            case SCSI_START_STOP_UNIT:
              // goto fail;
              MSC_StartStopUnit();   // <--- add these lines
              break;
            ...
            ...
            case SCSI_READ10:        // <--- change just the label to SCSI_READ12
              ...
              ...
            case SCSI_WRITE10:       // <--- change just the label to SCSI_WRITE12
              ...
              ...
            case SCSI_READ_TOC:      // <--- add these lines
              MSC_ReadTOC();
              break;
    
    void MSC_StartStopUnit (void) {
    
      CSW.bStatus = CSW_CMD_FAILED;
    
      if (CBW.CB[4] & 0x02) {             // check LOEJ (Load/Eject) bit
        if (CBW.CB[4] & 0x01) {           // check START bit
          //
          // load medium, if required
          //
        } else {
          //
          // unload medium, if required
          //
        }
        CSW.bStatus = CSW_CMD_PASSED;
      }
      MSC_SetCSW();
    }
    
    BOOL MSC_RWSetup (void) {
      ...
      ...
      /* Number of Blocks to transfer */
    //  n = (CBW.CB[7] <<  8) |      // <--- modify these lines
    //      (CBW.CB[8] <<  0);
    
      n =   (CBW.CB[6] << 24)
          | (CBW.CB[7] << 16)
          | (CBW.CB[8] <<  8)
          | (CBW.CB[9] <<  0);
     ...
    }
    
    void MSC_ReadTOC (void) {
               // check command parameters
      if (  ((CBW.CB[1] & 0x02) != 0)     // MSF field
         || ((CBW.CB[2] & 0x0F) != 0)     // Format-A field
         || ( CBW.CB[7]         != 0x00)  // Allocation Length MSB field
         || ( CBW.CB[8]         != 0x0C)  // Allocation Length LSB field
         || ((CBW.CB[9] & 0xC0) != 0x40)  // Format-B field
         ) return;
    
               // TOC header
      BulkBuf[ 0] = 0x00;      // TOC Data Length (= 0x0A)
      BulkBuf[ 1] = 0x0A;
      BulkBuf[ 2] = 0x01;      // First Complete Session Number (= 0x01)
      BulkBuf[ 3] = 0x01;      // Last  Complete Session Number (= 0x01 for single session)
               // TOC Track Descriptor
      BulkBuf[ 4] = 0x00;      // Reserved
      BulkBuf[ 5] = 0x14;      // ADR/CTL
      BulkBuf[ 6] = 0x01;      // First Track Number in Last Complete Session
      BulkBuf[ 7] = 0x00;      // Reserved
      BulkBuf[ 8] = 0x00;      // Logical Block Address of First Track in Last Session
      BulkBuf[ 9] = 0x00;
      BulkBuf[10] = 0x00;
      BulkBuf[11] = 0x00;
    
      BulkLen = 12;
      DataInTransfer();
    }
    

    Tsuneo

Reply
  • Both of USB drive (stick) and CD/DVD drive are supported by USB Mass-Storage Class, Bulk-Only Transport. Therefore, there is no difference on the USB protocol layer.

    The differences lie in the SCSI command layer.
    1) PDT (Peripheral Device Type): 00h (Direct-Access device, eg. USB drive) --> 05h (CD/DVD)

    2) Sector (Block) size: 512 byte --> 2048 bytes

    3) Required SCSI command set
    - READ10 --> READ12
    - WRITE10 --> WRITE12 (for CD-R/DVD-R)
    - Start/Stop Uint (optional --> required)
    - Read TOC (Not Available --> required) - information of sections/tracks on the CD
    -- see "5.1 READ TOC" on usb_msc_boot_1.0.pdf for bootable CD
    www.usb.org/.../usb_msc_boot_1.0.pdf

    Lastly, as of the contents on the CD image, see these specs.

    ECMA-119 (ISO9660)
    www.ecma-international.org/.../Ecma-119.htm

    Joliet Specification
    pierrelib.pagesperso-orange.fr/.../joliet_spec_v1.html

    “El Torito” Bootable CD-ROM Format Specification
    bochs.sourceforge.net/.../el-torito.pdf.gz




    > I've used RL-ARM mass storage code from sample codes of KEIL 4.03 on AT91SAM7S256.

    Is this example?
    C:\Keil\ARM\Boards\Atmel\AT91SAM7S-EK\RL\USB\RTX_Memory

    It's the first time I look in this example. With quick look, it looks like almost same as NXP LPC examples, except for the hardware layer.

    1) PDT
    PDT is reported in the reply to INQUIRY command.

    mscuser.c
    
    void MSC_Inquiry (void) {
    
      if (!DataInFormat()) return;
    
      BulkBuf[ 0] = 0x00;          /* Direct Access Device */   <--- 0x05 (CD/DVD)
      ...
    

    2) Sector (Block) size
    The sector size is defined in the mscuser.h
    It is applied to READ CAPACITY and READ FORMAT CAPACITY command, automatically.

    mscuser.h
    
    /* Mass Storage Memory Layout */
    #define MSC_MemorySize  8192  // <---- tune this size for the total CD capacity
    #define MSC_BlockSize   512   // <---- 2048
    

    3) Required SCSI command set
    Add definitions for the extra SCSI commands

    msc.h
    
    /* SCSI Commands */
    ...
    #define SCSI_READ12                     0xA8
    #define SCSI_WRITE12                    0xAA
    #define SCSI_READ_TOC                   0x43
    

    SCSI command parser is modified, as follows,

    mscuser.c
    
    void MSC_GetCBW (void) {
       ...
       ...
          switch (CBW.CB[0]) {
            ...
            ...
            case SCSI_START_STOP_UNIT:
              // goto fail;
              MSC_StartStopUnit();   // <--- add these lines
              break;
            ...
            ...
            case SCSI_READ10:        // <--- change just the label to SCSI_READ12
              ...
              ...
            case SCSI_WRITE10:       // <--- change just the label to SCSI_WRITE12
              ...
              ...
            case SCSI_READ_TOC:      // <--- add these lines
              MSC_ReadTOC();
              break;
    
    void MSC_StartStopUnit (void) {
    
      CSW.bStatus = CSW_CMD_FAILED;
    
      if (CBW.CB[4] & 0x02) {             // check LOEJ (Load/Eject) bit
        if (CBW.CB[4] & 0x01) {           // check START bit
          //
          // load medium, if required
          //
        } else {
          //
          // unload medium, if required
          //
        }
        CSW.bStatus = CSW_CMD_PASSED;
      }
      MSC_SetCSW();
    }
    
    BOOL MSC_RWSetup (void) {
      ...
      ...
      /* Number of Blocks to transfer */
    //  n = (CBW.CB[7] <<  8) |      // <--- modify these lines
    //      (CBW.CB[8] <<  0);
    
      n =   (CBW.CB[6] << 24)
          | (CBW.CB[7] << 16)
          | (CBW.CB[8] <<  8)
          | (CBW.CB[9] <<  0);
     ...
    }
    
    void MSC_ReadTOC (void) {
               // check command parameters
      if (  ((CBW.CB[1] & 0x02) != 0)     // MSF field
         || ((CBW.CB[2] & 0x0F) != 0)     // Format-A field
         || ( CBW.CB[7]         != 0x00)  // Allocation Length MSB field
         || ( CBW.CB[8]         != 0x0C)  // Allocation Length LSB field
         || ((CBW.CB[9] & 0xC0) != 0x40)  // Format-B field
         ) return;
    
               // TOC header
      BulkBuf[ 0] = 0x00;      // TOC Data Length (= 0x0A)
      BulkBuf[ 1] = 0x0A;
      BulkBuf[ 2] = 0x01;      // First Complete Session Number (= 0x01)
      BulkBuf[ 3] = 0x01;      // Last  Complete Session Number (= 0x01 for single session)
               // TOC Track Descriptor
      BulkBuf[ 4] = 0x00;      // Reserved
      BulkBuf[ 5] = 0x14;      // ADR/CTL
      BulkBuf[ 6] = 0x01;      // First Track Number in Last Complete Session
      BulkBuf[ 7] = 0x00;      // Reserved
      BulkBuf[ 8] = 0x00;      // Logical Block Address of First Track in Last Session
      BulkBuf[ 9] = 0x00;
      BulkBuf[10] = 0x00;
      BulkBuf[11] = 0x00;
    
      BulkLen = 12;
      DataInTransfer();
    }
    

    Tsuneo

Children
More questions in this forum