This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

USB MSC class and CD ROM subclass

Hi Dear Friends,
I've used mass storage code from sample codes of KEIL on AT91SAM7x.
And it works correctly and shows it as Flash memory in the windows.Then I changed it to apear as CD-ROM in windows.I have changed PDT and block size and added SCSI commands that requires.

Now I want to replace the contents of the disk image into CD one, which is formatted following to ISO966 spec . And there is my problem. I confused about it.In Primary Volume Descriptor should I placed the path table first and then placed the root? And I have problem with the path table itself too.

Can anyone help me about it? Or give me an example or tutorial about ISO?

I have used the Nero too to create ISO file but when it created the ISO File size is about 1 MB although I just put the same README.TXT that are in DISKImg.c and its size is just 94 B. What am I missing?

  • > I have used the Nero too to create ISO file but when it created the ISO File size is about 1 MB

    Nero makes Joliet extension for its ISO9660 option.
    You may make a compact .iso file using

    ISO Workshop
    www.glorylogic.com/.../

    Applying ISO9660 Level1 option on this utility, the size of .iso file which contains just the README.TXT is 45KB. This .iso file follows the ISO9660 spec well. Using a hex editor, you’ll learn how to allocate sectors.

    Tsuneo

  • > I confused about it.In Primary Volume Descriptor should I placed the path table first and then placed the root? And I have problem with the path table itself too.

    ISO Workshop made this .iso file which contains just README.TXT

    0x0000
      |       Reserved, filled with 0x00 (16 sectors)
    0x7FFF
    0x8000
      |       Primary Volume Descriptor
    0x87FF
    0x8800
      |       Volume Descriptor Set Terminator
    0x8FFF
    0x9000
      |       Path Table (Type L)
    0x97FF
    0x9800
      |       Path Table (Type M)
    0x9FFF
    0xA000
      |       Directory
    0xA7FF
    0xA800
      |       file contents (README.TXT)
    0xAFFF
    

    Tsuneo

  • Dear Tsuneo,
    I did what you said and as you said its size is 45 KB. I used the Winhex and copy the arrays to Diskimg. And I also change the

    #define MSC_MemorySize  45056
    #define MSC_ImageSize   45056
    

    But still when I programmed and attached the board to PC it just show the CD drive with no information (no size, no type, nothing)and also my computer halt when I click on the drive.
    I've searched and I founded http://www.keil.com/forum/21411/ in the forum.
    I found you a great man with lots of knowledge.And I really appreciate your help.
    I've missed something when I read the post and I added them according to you on that post.
    But the problem still is there.
    What do you think my problem is? What am I missing?

  • I used USBlyzer and this what I see.
    after 4 internal get status and 4 internal reset, there are 6 bulk transfer and then it got error.
    in the first bulk transfer this is what transfered:

    55 53 42 43 10 FC
    FB 0E 0C 00 00 00
    80 00 0A 43 00 01
    00 00 00 00 00 0C
    00 00 00 00 00 00
    00
    


    and then it repeats

    55 53 42 43 10 FC
    FB 0E 0C 00 00 00
    80 00 0A 43 00 01
    00 00 00 00 00 0C
    00 00 00 00 00 00
    00
    
    


    I dont know what it is. Can see what the requests are in this software?
    after that I used the USBTrace and they are same. After 4 internal device control, there are 4 bulk transfer and then it got error.
    I want to see the request like get_descriptor or set_descriptor and so on.Can see these requests or data transfer in this programs or I should use the serial port and Hyper Terminal?
    Can any one help me? why didn't windows recognize the CD ROM correctly?

  • Sorry for my long absence.

    In your last post, you asked about READ TOC (0x43) command.

    There are four types of this command, identified by its parameters
    1) MSF:0, FORMAT:0
    2) MSF:0, FORMAT:1
    3) MSF:1, FORMAT:0
    4) MSF:1, FORMAT:2 (format field is assigned to MSb 2bits of Control byte - legacy form)

    The return data blocks are slightly different each other.

    - Windows and Linux ask 1),2),3)
    - MacOSX retrieves 1),4)

    As of the details of this command, refer to SCSI MMC-6 (mmc6r02g.pdf)
    (search mmc6r02g.pdf)

    Here is the implementation

    //
    // READ TOC implementation
    //
    
    #define BIGLONG(x) (((x) >> 24) & 0xFF), (((x) >> 16) & 0xFF), (((x) >> 8) & 0xFF), ((x) & 0xFF)
    #define BCD(x)     (((((x) / 10) << 4) & 0xF0) | (((x) % 10) & 0x0F))
    
    #define LBA2M(x)   BCD( ((x) + 150) / 75  / 60)
    #define LBA2S(x)   BCD((((x) + 150) / 75) % 60)
    #define LBA2F(x)   BCD( ((x) + 150) % 75)
    
    #define LBA2MH(x)   ( ((x) + 150) / 75  / 60)
    #define LBA2SH(x)   ((((x) + 150) / 75) % 60)
    #define LBA2FH(x)   ( ((x) + 150) % 75)
    
    const U8 SCSI_TOC_LBA0[] = {
           // TOC response header
      0x00, 0x12,             // Data Length
      0x01,                   // First Track
      0x01,                   // Last Track
           // track descriptor 1
      0x00,                   // Reserved
      0x14,                   // ADR/CONTROL
      0x01,                   // Track Number
      0x00,                   // Reserved
      0x00, 0x00, 0x00, 0x00, // start address in MSF format (fixed)
           // track descriptor 2
      0x00,                   // Reserved
      0x14,                   // ADR/CONTROL
      0xAA,                   // Track Number: Lead-out area
      0x00,                   // Reserved
      BIGLONG( MSC_BlockCount )  // Lead-out start address in MSF format
                              // (variable, depending on the size of track 1)
    };
    
    const U8 SCSI_TOC_LBA1[] = {
           // TOC response header
      0x00, 0x0A,             // Data Length
      0x01,                   // First Track
      0x01,                   // Last Track
            // track descriptor
      0x00,                   // Reserved
      0x14,                   // ADR/CONTROL
      0x01,                   // Track Number
      0x00,                   // Reserved
      0x00, 0x00, 0x00, 0x00  // Track Start Address
    };
    
    const U8 SCSI_TOC_MSF0[] = {
           // TOC response header
      0x00, 0x12,             // Data Length
      0x01,                   // First Track
      0x01,                   // Last Track
           // track descriptor 1
      0x00,                   // Reserved
      0x14,                   // ADR/CONTROL
      0x01,                   // Track Number
      0x00,                   // Reserved
      0x00, 0x00, 0x02, 0x00, // start address in MSF format (fixed)
           // track descriptor 2
      0x00,                   // Reserved
      0x14,                   // ADR/CONTROL
      0xAA,                   // Track Number: Lead-out area
      0x00,                   // Reserved
      0x00,                   // Lead-out start address in MSF format
      LBA2M( MSC_BlockCount ), // (variable, depending on the size of track 1)
      LBA2S( MSC_BlockCount ),
      LBA2F( MSC_BlockCount )
    };
    
    const U8 SCSI_TOC_MSF2[] = {
           // TOC response header
      0x00, 0x2E,             // Data Length
      0x01,                   // First Track
      0x01,                   // Last Track
           // track descriptors
    // Session ADR/CTRL  TNO   POINT  Min Sec Frame  ZERO PMIN PSEC PFRAME
        0x01,    0x14,   0x00, 0xA0, 0x00,0x00,0x00, 0x00,0x01,0x00,0x00,
        0x01,    0x14,   0x00, 0xA1, 0x00,0x00,0x00, 0x00,0x01,0x00,0x00,
        0x01,    0x14,   0x00, 0xA2, 0x00,0x00,0x00, 0x00,LBA2MH( MSC_BlockCount ),
                                                               LBA2SH( MSC_BlockCount ),
                                                                    LBA2FH( MSC_BlockCount ),
        0x01,    0x14,   0x00, 0x01, 0x00,0x00,0x00, 0x00,0x01,0x02,0x00,
    };
    
    void MSC_ReadTOC (void) {
    
      U32 n = (CBW.CB[7] << 8) | CBW.CB[8];  // allocation length
      U8 msf    =  CBW.CB[1] & 0x02;
      U8 format = (CBW.CB[2] & 0x0F) | (CBW.CB[9] >> 6);
    
      if ( (msf == 0) && (format == 0) )
      {
        BulkLen = sizeof(SCSI_TOC_LBA0);
        BulkPtr = (U8 *)SCSI_TOC_LBA0;
      }
      else
      if ( (msf == 0) && (format == 1) )
      {
        BulkLen = sizeof(SCSI_TOC_LBA1);
        BulkPtr = (U8 *)SCSI_TOC_LBA1;
      }
      else
      if ( (msf == 2) && (format == 0) )
      {
        BulkLen = sizeof(SCSI_TOC_MSF0);
        BulkPtr = (U8 *)SCSI_TOC_MSF0;
      }
      else
      if ( (msf == 2) && (format == 2) )
      {
        BulkLen = sizeof(SCSI_TOC_MSF2);
        BulkPtr = (U8 *)SCSI_TOC_MSF2;
      }
      else
      {
        MSC_SetStallEP(MSC_EP_IN);
        CSW.bStatus = CSW_CMD_FAILED;
        sense_error_num = SENSE_INVALID_COMMAND_OPERATION_CODE;
        MSC_SetCSW();
        return;
      }
    
      if ( BulkLen > n ) BulkLen = n;
      DataInTransfer();
    }
    

    Tsuneo

  • Also, here is an example for AT91SAM7X

    homepage2.nifty.com/.../AT91SAM7EX256_USB_CDROM.zip

    - Based upon Keil MDK-ARM v4 example
    \Keil\ARM\Boards\Atmel\AT91SAM7X-EK\USB\Memory

    - Ported to Olimex SAM7-EX256

    - Tested on Windows7 (x64/x32), MacOSX 10.9.4, Ubuntu 14.04.1 LTS

    This example emulates USB CDROM on AT91SAM7X
    which has single ReadMe.txt file.

    To make up your own CDROM on this firmware,
    1) Using ISO Workshop (see above post), drop in your files into an ISO image.
    2) Convert the .iso image file into C code file, using SRecord
    http://srecord.sourceforge.net

    > srec_cat DiskImg.iso -binary -o DiskImg.c -C-Array

    3) Replace DiskImg.c of this example with yours.

    Enjoy!

    Tsuneo

  • Dear Tsuneo,
    I can not download the sample you uploaded.Could you upload it on another server?
    Thank you again for your great help to me. I never forget it.

  • I posted the example to Atmel AT91 forum with a brief implementation summary.
    www.at91.com/.../p,42763.html
    - down load attached file to this post on Atmel

    Tsuneo