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
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
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(); }
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!
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