Sean Keller and Chris Bartholomew|
EE 476 Final Project for Prof. Bruce Land|
May 2, 2001
The Zip Drive
|SCSI Interface||Serial Data Port|
|Intro |||Design |||Program/Hardware |||Results |||Next Time |||Conclusion |||Appendices|
IntroductionThe original motivation behind our project was a desire to interface with some type of real world device. Since one of the clear limitations of the Atmel chipset is the lack of storage space, we felt it would be useful if we could connect to some type of mass media storage device. Implementing a SCSI interface would allow us to connect to virtually any type of storage device - hard drives, CD-ROM drives, and various removable media. Since Sean had a SCSI Zip drive lying around his apartment, our project concept began to come together.
However, we felt that connecting to a Zip drive wouldn't do much by itself; we needed some data to store! After some research, we found that there were digital cameras that would connect through a serial port and had a simple programming interface. This was the perfect application of the Zip drive's 100 MB storage capacity.
We have designed a board, using two of Atmel's 90s8515 8-bit microcontrollers, that will retrieve a picture from a Barbie Cam and store that image onto a Zip drive with the press of a button. Additionally, our device can take stop-motion video and store the images in a numbered sequence of files. It is necessary to run these images through a Java program that will interpolate the raw pixel data into a readable bitmap file.
Although our project focuses on the Zip drive and Barbie camera, our project would also be able to handle data from any serial source and store it onto any type of SCSI-2 device with some minor code changes. A really neat feature of SCSI is that it's totally backwards compatible, so any modern SCSI device can easily communicate as a single ended asynchronous device and thus interface with our board
High Level DesignAs mentioned above, we are using two Atmel microcontrollers in our project; one is responsible for interfacing with the camera, and one with SCSI. The camera chip connects to the camera through the UART at 57,600 baud. There are two buttons connected to the camera chip for taking snapshots and stop-motion video. The main while loop of the camera chip will test if either the snapshot button is pressed or the chip is in video mode. If so, the camera chip will send a few commands over the UART connection, and the camera will respond by streaming 20,680 bytes of picture data over the serial port. The camera chip buffers the image into external memory, and then transfers the data byte by byte to the SCSI chip.
The data transfer code uses four pins for data (to conserve usage of the I/O pins) and four for control. The SCSI chip controls the data transfer procedures by either requesting that an image byte be sent from the camera chip or that data be stored in/retrieved from the camera chip's external memory.
When the SCSI chip receives its first data, it constructs a new file on the Zip drive in the file allocation table (FAT) of the disk. It then writes the image data to the Zip drive byte by byte. The SCSI protocol allows the usage of an asynchronous handshake for each byte transferred, which we took advantage of since our microcontrollers couldn't handle fast, synchronous SCSI transfers. Additionally, the SCSI chip has its own UART which can be used to browse the contents of the Zip drive's root directory using the familiar DOS "dir" command and eject the Zip disk remotely by using an "eject" command!
Program and Hardware DesignThe first steps in our design was to construct our prototype board. We first soldered two ZIF sockets onto the board and connected the data transfer pins together. We then proceeded to connect the external SRAM, latch, RS-232 transceiver, LED's and buttons just as given in the STK-200 board schematics. Finally, we attached a SCSI port. At first, we connected the SCSI port through a passive termination circuit before connecting them to the 8515 pins. We then quickly realized that the passive termination circuit gave a 30 ohm connection from Vcc to GND, which would draw roughly 200 mA just from sitting there. We then opted to connect the SCSI connector directly to the 8515 pins and avoid using termination. After some tests, we also realized that we needed to turn termination off at the Zip drive, since the 8515 pins couldn't sink enough current in order to ground the SCSI pins. We were concerned that without termination, signals on the SCSI bus would be reflected and cause errors. However, since the cable distance is short enough and our transfer rates are slow enough, we have not run into any problems.
We then constructed our chip to chip transfer code. Four pins were used for data, and data can be transferred in either direction. There are also four control pins, which form two REQuest/ACKnowledge pairs - one for image data and one that allows the SCSI chip to store information in the external memory. The SCSI chip controls which data it would like to be sent. If it pulls the REQ for image data high, the camera chip responds by placing a nibble of image data onto the data pins (it will block until image data is available). The SCSI chip drops the REQ line when the data has been received, which is followed by the camera chip doing the same.
The SCSI chip can also pull the REQ line for RAM use high, but the process works differently. Due to the fact that you can only read/write a 512 byte sector at a time to the Zip drive, the SCSI chip will need 512 bytes of storage space to back up data. The SCSI chip will always back up 512 bytes and then restore 512 bytes before backing up again. We exploited this fact in order to simplify our chip to chip data transfer logic. The camera chip will always know whether the SCSI will be sending data or receiving data when the corresponding REQ line goes high. It can then take the appropriate action, set its ACK line high, and then drop the ACK once the SCSI chip drops its ACK. This process requires only two handshaking pins, rather then requiring the SCSI chip to inform the camera chip which direction to transfer data.
The code for the camera chip came next. First, we initialized the UART to connect at a baud rate of 57,600 due to the requirements of the Barbie Cam. We then had a main while loop that would poll the snapshot button or whether continuous capture mode was on. If so, it would send a series of commands to the camera over the UART. All commands begin with STX (0x02 in hex), then a capital letter representing the command, then 0, and finally an ETX (0x03 in hex). First, we sent an 'A' to reset the image index to zero, since the Barbie Cam can store 8 images in memory. It then sends a 'G' which causes the camera to take a snapshot. Another 'A' is sent to reset the image index to zero once again, so that a 'U' command can be sent in order to upload the picture. The camera then streams image data over the UART, which the camera chip stores in a giant 20,680 byte array in external memory. It then makes a blocking call to send the data, byte by byte, over to the SCSI chip.
We then began to tackle the difficult SCSI device driver. To begin, here is some SCSI Pseudocode and SCSI Specifications. SCSI has various states that it may be in at any given time. You begin in the Bus Free state, which means that no devices are sending data or have control of the SCSI bus. Our chip immediately moves into Arbitration mode in order to win control of the SCSI bus. Since our board uses a SCSI ID of 7, which has the highest priority, we automatically win the SCSI bus during Arbitration. We can then tell the Zip drive that we would like to communicate with it. The Zip drive responds by requesting a message or a command, which we can send to it. As shown in the pseudo-code, the commands we send depend upon the situation. Once a command has been completed, we simply ignore the status code and message returned afterwards (we assume that the operation has successfully completed). SCSI commands consist of a series of bytes, where each byte is individually handshaked to the receiving device. The first byte specifies the command to perform, and the rest are the parameters of the command. If a read or write command has been given, then the command bytes are immediately followed by data transfer, where each byte is also individually handshaked.
We then began to write code that would handle the FAT file system. We didn't quite have time to finish this phase, as noted in the results. The FAT table keeps track of how all the clusters on the Zip drive are used. A file's clusters do not need to be contiguous, so the FAT is essentially a linked list of what clusters the file uses. A directory entry points to the first cluster, and then the remaining clusters can be found by looking up the FAT table. A directory entry is 32 bytes in size, and keeps track of various file attributes. The table for the root directory is kept immediately after the 2 FAT tables.
ResultsOur device is 99% functional. We are able to use our board to take single snapshots and stop-motion video. Our HyperTerminal interface allows for browsing the file system and ejecting the zip disk. The SCSI device driver works, and we are able to write images to the zip drive. But, we just couldn't quite get the FAT file system to work. We are able to write to the root directory, and update the FAT table. So, when we examine the zip disk on a Windows machine, we can see our file and access it. It is correctly attributed as a file, has no time stamp, and has the correct length. The first cluster of information is correct, but the FAT is broken and does not correctly link us to the next cluster in the chain. Honestly, we can probably fix this in about 2 hours, but we just don't have 2 more hours today to work on this project.
Our device is also quite speedy. We are able to take a snapshot and store it in about 8 seconds. We never clocked the SCSI interface, but it certainly was as fast or faster then 115200bps, because we were able to read at this speed and dump the output to HyperTerminal.
As to accuracy, we have never seen chip to chip or Zip drive transfer errors, so we are confident there is no data corruption. The pics captured with the digital camera look accurate, but we need to write an interpolation routine to actually verify their content.
In terms of usability, our setup is pretty good. The control buttons and HyperTerminal interface along with various LEDs allow for very simple operation. It isn't very portable, but could easily be made portable. With a bit of tweaking the Board could easily be made to consume very little power and run of batteries. Also, there is a Zip Drive battery pack commercially available, so we could easily make our device highly portable. The Hyperterminal interface is mainly for debugging, and is not useful for taking and storing pictures, so it wouldn't make portablility difficult.
What We Would Do Differently Next TimeGiven an opportunity to do things all over again, the first thing we would do differently is to plan and design our board layout entirely before beginning to build it. We spent roughly 40 man-hours soldering and wiring the hardware together, and it would have been nice if we had finished the board ahead of schedule. We could have used the extra time to tinker with the Zip drive more, since building a SCSI driver is no easy task. Also, we definitely should have placed an on/off switch on the board since we incorrectly assumed that just plugging the adapter in and out would be fine.
With that extra time it would have been nice to add more support for the FAT file system. We had to restrict ourselves to storing images and browsing only the root directory due to time constraints. It would have been nice to add the DOS "cd" command so that the user could browse the entire contents of a Zip disk from Hypterminal, as well as saving his images to the directory of choice.
The next item in our list of things to do next time is to make our device entirely SCSI 2 compliant. The 25pin SCSI adapter is not an official adapter. The Zip drive uses it and it is used in many Macintosh systems, but it is not part of the SCSI standard. We would probably use a high-density 50-pin or 68-pin standard SCSI adapter for an official SCSI A-type cable. Next, we would definitely terminate the bus on both sides. We chose not to terminate because it required us to sink more current with the 8515 then the ports can handle. We did think of several workarounds that would allow us to use Active Termination on both sides of the bus, such as connecting a BJT to each pin, but we didn't test our ideas. Finally, we didn’t check and account for every possible standard SCSI-2 error condition, because they just never seem to occur with the Zip drive. If given more time we could easily add checks for these error conditions.
The final item on our list of things we would have liked to do is to build an interpolation routine for the pictures we capture. This is not a very difficult task to accomplish as the Bayer color pattern used by the camera is very common, and there are many well-established interpolation routines that we could implement.
ConclusionEverything worked out very well in the end, but it was quite a journey. Along the way, we encountered many stumbling blocks, which we were able to eventually overcome. The most difficult part of the project was building the SCSI device driver. We learned rather quickly that playing with SCSI at the physical level is an awesome task. We primarily used the ANSI SCSI-2 Committee X3 draft, because it is free and available online. The problem we encountered was that the document is really a specification of the standard and intended as a reference not as a learning tool. We overcame this problem by spending about 30 man-hours with test code, the Zip drive, and a voltmeter. After this initial learning curve, SCSI became an understandable and friendly interface that we could easily work with and code for.
One of the most annoying and disheartening moments occured two evenings before our project was due; we unknowingly inserted a ‘Double Click of Death’ infected Zip disk into our drive, which destroyed the read-head. Amazingly we were able to purchase a 250Mb SCSI Zip drive the next morning. Quite fortuitously, all or our code still worked on the newer drive, since we did indeed follow the SCSI-2 standard very closely. We’d like to take a moment to thank Iomega for building a product that can be destroyed by a simple hardware virus.
All in all, we were able to plan, design, prototype, debug, and complete an original piece of hardware. Our device clearly has flaws, but it is just the first prototype. It demonstrates that building a SCSI-2 compliant interface using a simple MCU is both doable and useful.
Appendix I: Program ListingSCSI Pseudocode
Chip to Chip Data Transfer Code: send.c | receive.c
Camera Chip Code: camera.c
SCSI Chip Code: scsi.c
Java Interpolator: RawDataConverter.java
Appendix II: Hardware SchematicsParts List:
(2) Atmel 90s8515 microcontrollers
(2) 7.2738 MHz crystals
(1) Maxim RS-232 transceiver
(1) 9-pin male port
(1) 9-pin female port
(1) 25-pin female port
(1) 32 KB external SRAM
(1) 8-bit latch
(1) 110V 60Hz AC to 12V DC transformer (200mA max)
(1) 5V voltage regulator
(1) Power adapter plug
(1) Prototype board
(2) Push buttons
(X) Various resistors, capacitors, and wires
Figure 1: Board Schematic
Figure 2: External RAM/Latch Connection (Detailed)
Figure 3: RS-232 Port Connection
Image 1: The top of the board
Image 2: The bottom of the board
Image 3: Our lab setup
Image 4: Another one of our lab setup
Appendix III: ResourcesCCD Datasheet: STMicroelectronics
FAT file system: The PC Guide
SCSI FAQ: SCSIFAQ.org
The Linux SCSI Programming HOWTO: Students Only Research Yard
ANSI SCSI Specifications: ftp.cs.uni-sb.de/pub/misc/doc/SCSI
Copyrightă 2001 Sean Keller and Chris Bartholomew