Sunday, 12 January 2014

DMA Support (at last)

The initial implementation of DMA for SPI is based on recent examples of using the Pi DMA hardware from user mode rather than from a kernel driver. This is an approach for the impatient and the foolhardy as it bypasses the kernel to access the DMA hardware registers directly but has the advantage of quick prototyping and overhead.

The Raspberry Pi has 16 DMA channels. Channels 1,3,6 and 7 are reserved for the GPU. Various sources indicate that channels 0 and 2 are also used by the system. SPI requires two channels, one for sending and one for receiving. I am using channels 13 and 14 for SPI DMA and so far have not encountered problems. These channels are "Lite" channels which have less capabilities than channels 0-7 but seem to be sufficient for SPI transfers

SPI DMA runs at at approximately 4 MHZ. Much to my surprise the input signal is continuous unlike the non-DMA signal which has a one clock cycle gap between bytes. A sample from my logic analyzer is shown below and comparing this signal with the raw data confirms that there are no gaps. This results in a substantial improvement in the data quality and I hope to implement MFM decoding support in the future.

SPI DMA - Data on top, SPI clock on bottom. (Data signal inverted as I was recording from a different pin)

SPI without DMA. Note the gaps in the SPI clock signal where no data is recorded.

In binary notation the SPI DMA signal from the disk drive looks like this:
This is a sequence of four FM data/clock pulses. The raw pulses are about 4-5 'bits' wide which corresponds to about 1 microsecond. The gaps between the raw pulses are about 12 bits wide which corresponds to about 3 microseconds. This closely matches the specifications of the original floppy disk controller on the TRS-80. The task of the software is to measure the spacing of the pulses and turn them into FM disk encoding. I am able to record copy-protected disks and run them on various emulators successfully.


I have also built the first PCB. I have designed other PCBs but this is the first one I have etched and drilled myself. A picture of the PCB is below. It is single sided to make it easier to build. The large areas of bare copper were left to make the etching compound last longer. The cable from the floppy disk drive plugs into the connector to the right. The connector that plugs into the Raspberry Pi is mounted below the board on the left side. The corner cut out on the top left is to clear the RCA video connector. I have a few improvements in mind for the layout to make soldering easier and to provide some pins to connect the logic analyzer. In theory it would support writing to the floppy drive but there is no software support for that at present.