This little project aims to create a USB CD-ROM device. Unlike the typical deviced which tries to imitate this isn’t a real CD-ROM drive, it just emulates it. The idea is to allow the user to store a ISO image or other kind of CD-ROM image in a SD card to expose it as a CD-ROM to the computer.
At the time of writing it works quite well, only tested with ISO images and doesn’t allow hot extraction of the SD card. This will be fixed, but requires some tweaks on SCSI commands and responses in order to allow the host to eject the CD too.
The schematic is prepared for media sensing, as represented by the switch connected to RB7. My SD card slots have 2 pins which get shorted when a card is inside the slot.
The card works at 3.3V so a 5V to 3.3V converter is needed in case you want to supply the circuit with the USB voltage source. This is done by using a simple zener and a resistor. Be careful with the values and the power dissipated, some parts may become hot!
The device exposes a MSD to the USB host. You can have a look at Microchip examples for reference and the USB MSD spec. It’s important to use wireshark to debug the commands and their responses, this way you’ll know where the host gets stuck (typically when device sends bad respones the host keeps trying and trying over and over again triggering device resets too).
The most important part are the SCSI commands. They are poorly documented for CDROM drives (as opposed to disk drives) so it’s crucial to have a reference to have a look. I used a Sandisk U3 pendrive which features CDROM emulation for storing internal programs (so they can’t be removed and can be autoruned!).
I won’t get into details, just simple description. You need to fill the descriptors properly (have a look at a pen drive with wireshark and the USB specs.) and setup 2 bulk endpoints (IN & OUT) to tranfer data. The data and the SCICS commands/responses will travel using those EP. It’s important to fully understand the CBW and CSW structures and make a good use of them.
I have some data hardcoded (such as SD capacity) because the SD card is driving me mad, but you should be able to change everything to be dynamically calculated.
It works great under Windows (tested with Wireshark and VirtualBox under Linux host) and Linux, but it doesn’t automount the disk. I dunno if it’s an error, but Sandisk’s doesn’t get mounted too, so it’s not my fault at all! SCSI commands are a headache, just return the Command not Valid error when you don’t know what to do. That usually makes the whole thing work.
I haven’t been able to boot from the CDROM, as opposed to the disk emulation. I think it’s a BIOS related problem, so no worries at all. I’d like to be able to debug the BIOS, but it’s almost impossible given that VirtualBox doesn’t support USB boot :(
Almost forgot! To copy the ISO to the SD card you have to copy using dd command and overwriting all the data (including MBR, partition table, etc.) so the entire card content is an ISO9660 media. In the future I will implement copying ISOs inside FAT partitions, this way I could emulate floppy, cdrom, etc. using the same device. I have in mind an IP KVM, having emulated mouse and drives only keyboard and VGA capture lasts.
An screenshot is always a good conclusion, right?