Table of Contents

Emulating An USB CDROM on STM32F103C8


The source codes from STMicroelectronics for their popular STM32 consists of an USB mass storage device class. I did some improvement to the source and emulated a tiny USB CDROM. I just connected a 512KB spi flash chip as a DISC and burnt a small ISO9660 image file into it. That's why I called it tiny. The original source code supports only a minor collection of SCSI requests. I extended the sources to support extra commands. Because of the very small capacity of the spi flash chip, I had to build a tool to analyse the ISO9660 disc image and cut down its size. I also built a tool to burn the disc image into the flash chip through some custom SCSI commands. Unfortunately both of these tools are working on Windows platfrom. I don't know much about coding on Linux.

STEP 1: Hardware Design

I choosed the Bluepill board as the main controller, which has two SPI ports to be used to connect serial flash or TF card. I configured the SPI2 as a master port with 8bit data size. Pin PB12 was used as the CS signal generator which was controlled by the firmware. The SPI1 was configured as well but unused in this project. I connected a serial flash chip to the Bluepill as the DISC. Unfortunately I just had some obsolete tiny flash chips (AT45DB041B). That means I had to build a tiny ISO9660 disc image file which could be burnt into this flash chip.

STEP 2: Firmware Generate

Generate Firmware source code with STM32CubeMX:

STEP 3: Coding and Compile

Some codes (SELECT/DESELECT/SPI_Xxx) are derived from eziya's STM32_SPI_SDCARD project.

I compiled the source codes with GCC (arm_none_eabi) under EmBitz and debug with my brand new homemade CMSIS-DAP JTAG probe. ;-)

STEP 4: Build and Burn ISO9660 disc image

I chose Folder2Iso to generate a ISO9660 disc image file. Because of the small capacity of AT45DB041B, I had to build a tool to trim the image file. Please refer to iso9660 project in Win32 directory. Some source code comes from gootqt's blog: ISO9660文件系统分析.

The disc burn tool (MSC_Test project in Win32 directory) is a little bit tricky. I used the func “GetMscDeviceContext” to get the pathname of the USB CDROM. If you have another USB CDROM which has been connected to the host, please unplug it or check the strings of manufacturer/product retrieved via INQUIRY command. If you try to use VID/PID to detect the CDROM, please refer to this webpage on stackoverflow.com. I left some source codes (the funcs “GetDrivesDevInstByDeviceNumber” and “matchDevInstToUsbDevice”) which was from this webpage in my project.