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!
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
Hi Tsuneo!
Thanks for your first help!
I changed codes according to your help and loaded it to my board and attached it to a PC. It appeared as a CD-ROM in different versions of windows (WIN& & XP)(x64 & x32).
But there is a problem, it didn't work correctly. Then I debugged it and I found that the MSC_ReadTOC function returns at if. . . at the beginning of function, because some of condition is true and it becomes true and the function returns. according to usb_msc_boot_1.0.pdf document , CBW.CB elements must be differ from what are now.
whats your idea about this!
And one another question: Original sample code of atmel consist of one image of a text file , that is copied to ram for demo in USB drive (stick) state, and the ram is the storage media. So when we attached it to computer we see a text file in it .Now we change the code to CD-ROM state , must we see it in cd-rom as before or cd-rom can't show it because of CD IMAGE concepts or other reason?
You are best helper for this forum, thank you for your reply again. :)
View all questions in Keil forum