2301012.PDF

(1444 KB) Pobierz
APPLIED
PCs
Fred Eady
Atmel ATmega128 with RS-232,
Ethernet, and 64-KB of external 16-bit
memory? Well, this project is for you
too. Hard drives or no hard drives,
let’s get started.
THE HARDWARE
Hanging a standard PC or laptop
hard drive from the 40-pin connec-
tor shown in Photo 1 is the reason
why we’re gathered here today. I
wanted the ATA hard drive con-
troller’s electronics to be flexible. So,
in addition to the standard RS-232
port, which is driven by a Sipex
SP233ECT, I added 10-Mbps Ethernet
capabilities with the RTL8019AS/
LF1S022 combination.
The ATmega128 has plenty of
internal SRAM (4 KB), but I thought
adding 64 KB of 16-bit external
SRAM would be nice. Adding the
SRAM is sort of like buying rope:
you can always make the rope short-
er, but it’s a pain to add rope later if
you need it.
The ATmega128 has enough I/O
structure to service the big SRAM
with some help from a couple of
74HCT573 latches. As you can see in
Figure 1, the external SRAM is
attached to the ATmega128 in the
standard manner. This allows those
of you who aren’t interested in plac-
ing bits on a spinning piece of mag-
netically coated aluminum to do
your thing with the big chunk of
SRAM and the raw power of the
ATmega128. With the SRAM in this
configuration, the results of the hard
drive I/O operations can be buffered
by the external SRAM or operated on
by the AVR directly.
Construct an ATA Hard
Drive Controller
It’s about time you had
full control of your hard
drive. The controller
you’ve been waiting for
is just one project
away. This month,
Fred shows you how
easy it is to build an
ATA hard drive con-
troller. Amazingly, all
you need is a good
micro and a few every-
day parts.
Circuit Cellar, the Magazine for Computer Applications. Reprinted
by permission. For subscription information, call (860) 875-2199, or
www.circuitcellar.com. Entire contents copyright ©2001 Circuit
Cellar Inc. All rights reserved.
o you remember
your first comput-
er with a hard drive?
What about when 5 MB
was a lot of hard drive space? Have
you ever wanted to put something of
your own on a hard drive without
having to rely on somebody else’s
expensive and proprietary hardware
and driver code? Ever want to read,
write, and control a hard drive with a
microcontroller?
If you answered “yes” to any one
of these questions, then this project
is for you. I’ll show you how to build
an ATA hard drive controller with a
microcontroller and a few common
parts. In addition, you’ll learn
how to write simple code that
will form the basis for deploy-
ing a stand-alone, networkable,
microcontroller-based data
storage system.
Even if you aren’t interested
in communicating with hard
drives, there’s something here
for those of you who don’t need
a microcontroller-driven hard
drive controller. The bonus
track is in the hardware. Do
Photo 1—
The board is clean and simple. All of the supporting
you need an in-system program-
capacitors and resistors are SMT parts mounted on the oppo-
ming-capable test stand for an
site side of the board.
CIRCUIT CELLAR
®
Issue 150
January 2003
d
www.circuitcellar.com
1
Listing 1—
A core set of registers is the gateway to the hard drive platters. Everything needed to access a
particular data point on the hard drive is represented here.
//ATA I/O port functions and address definitions
//Control block registers
//
RESET
//
|DIOW
//
||DIOR
//
|||DA0
//
||||DA1
//
|||||DA2
//
||||||CS0
//
|||||||CS1
//
||||||||
#define ATA_IO_HIZ
0b11111111
#define ATA_IO_ASTAT
0b11101110
#define ATA_IO_DEVICECNTL
0b11101110
//Command block register addresses
#define ATA_IO_DATA
0b11100001
#define ATA_IO_ERROR
0b11110001
#define ATA_IO_FEATURES
0b11110001
#define ATA_IO_SECTORCNT
0b11101001
#define ATA_IO_SECTORNUM
0b11111001
#define ATA_IO_CYL_L
0b11100101
#define ATA_IO_CYL_H
0b11110101
#define ATA_IO_DEVICE_HEAD
0b11101101
#define ATA_IO_STATUS
0b11111101
#define ATA_IO_CMD
0b11111101
The Ethernet interface, shown in
Figure 2, is actually a wire-by-wire
copy of the Packet Whacker micro-
controller NIC. The original Packet
Whacker firmware that was written
for the ATmega series of AVRs is
used in the ATA hard drive con-
troller code, as well. The Packet
Whacker code already has hooks to
allow for the easy transmission and
reception of the hard drive data.
The RS-232 port has a dual purpose.
Running at 57.6 kbps, it’s fast enough
to spit out a sector’s worth of ASCII
data to a terminal emulator for debug-
ging. In addition, it can be used effi-
ciently in an application to transfer
data and commands between the
AVR-based hard drive controller and a
peripheral device. The 10-pin header
makes assembling a serial cable easy,
if you use 9- or 25-pin IDC shell con-
nector parts and ribbon cable.
I’ve standardized with 10-pin male
headers for all of the external ports
with the obvious exceptions of the
Ethernet and hard drive I/O ports. As
long as you put the right connector
in the correct header socket, using
the 10-pin headers with the keyed
shrouds eliminates the possibility of
inserting the ISP and serial connec-
tors incorrectly.
The 10-pin arrangement is also
standard for most of the ISP dongles
that support the AVR series of ISP-
Figure 1—
No surprises here, either. The craftiness of this design lies in the way the firmware utilizes the hardware resources.
2
Issue 150
January 2003
CIRCUIT CELLAR
®
www.circuitcellar.com
capable microcontrollers. I used a
Kanda AVR ISP dongle and a version
of the company’s ISP software to pro-
gram the hard drive controller’s
ATmega128. Because the dongle
interface is dedicated to certain pins
on the AVR and power isn’t trans-
ferred within the programming cable,
I was able to keep the dongle
attached to the hard drive controller
throughout the programming and
debugging process.
The ATmega128 is clocked at
14.746 MHz to keep the data rate
error percentage at a minimum for
the 57.6-kbps serial port. For this
project, the ATmega128 I used was a
5-V part that can run at 16 MHz.
The 14.746 MHz is the closest stan-
dard crystal to the maximum clock
speed that will clock the big AVR
with the least amount of serial data
bit error rate.
The first spin of the ATA hard drive
controller used a 2-mm header that
mated directly to the 44 I/O pins
found on 2.5″ laptop drives. My expe-
riences with the 2-mm parts were not
good ones. The pins and connectors
are fragile, and I really don’t like
working with the 1-mm ribbon cable.
In the process of attempting to work
at 2 mm, I purchased a gaggle of new
surplus 2.5″ Hitachi 540-MB drives.
That purchase, as it turns out, was a
good thing. After junking the 2-mm
idea, I purchased some surplus 850-MB,
3.5″ drives that turned out to be most-
ly junk. I never really had any inclina-
tion to put real data on them, so it’s
not a total loss. At less than $10 per
drive, what did I expect?
When I bought the laptop drives, I
also purchased some 2-mm to 0.1″ (or
2.5″ to 3.5″) converter boards. The
idea was to be able to attach the lap-
top drives to a PC for the debugging
and verification of the ATA drive con-
troller’s firmware and hardware.
The moral of the 2-mm hard drive
story is that, thanks to my foresight,
you’ll see how I brought the ATA hard
drive controller to life with the 2.5″
Hitachi drives and converter boards.
This may sound funny, but when I
was formatting the 3.5″ 850-MB
drives, I was hoping that a few of
them would show some errors. I want-
ed to verify that the hard drive con-
troller could detect them, and then
show you what they looked like. I
really didn’t expect them to be trashed
so badly. So, the drive error examples
will come from the 3.5″ drives, and
the good data examples will feature
the smaller Hitachi drives.
The ATA hard drive controller
requires a single 5-VDC power source.
Also, the Hitachi drives require only
Figure 2—
If this looks familiar, it’s because it’s actually a Packet Whacker that’s been melded into the ATA controller design. The Packet Whacker code was reused, as well; it
can be found wound into the ATA controller source.
www.circuitcellar.com
CIRCUIT CELLAR
®
Issue 150
January 2003
3
Listing 2—
Because the routines are identical, with exception to the status bit that’s checked, I took some
liberties and squashed all three
ready
,
busy
, and
error
routines into a single function to save some
space. The unsigned
int ata_bsy(void)
function includes the
if(ata_byte_read &
ATA_STAT_BSY)
line and the other two functions follow the same logic.
#define recalibrate
ata_send_cmd(CMD_RECALIBRATE)
#define CMD_RECALIBRATE
0x10
#define PORT_ATA_IO_CNTL
PORTF
#define ATA_DIOR
0x20
#define PORT_ATA_DATA_L_IN
PINA
#define ATA_STAT_BSY
0x80 //ATA busy
#define ATA_STAT_RDY
0x40 //ATA ready
#define ATA_STAT_ERR
0x01 //ATA error
#define busy
ata_bsy()
#define drq
ata_drq()
#define error
ata_err()
#define ready
ata_rdy()
#define hard_reset
ata_hard_reset()
#define select_device_0
ata_select_device(0x00)
#define select_device_1
ata_select_device(0x01)
#define recalibrate
ata_send_cmd(CMD_RECALIBRATE)
#define identify_device
ata_send_cmd(CMD_IDENTIFY_DEVICE)
*****************************************************************
Initialize drive. This routine assumes drive 0 is the only drive
that is attached.
*****************************************************************
void init_ata(void)
{
while(!ready & busy);
hard_reset;
delay_ms(10);
while(!ready & busy);
select_device_0;
while(!ready & busy);
recalibrate;
while(busy);
if(error)
printf("ERROR!");
printf("\r\nDrive is READY!\r\n");
//Functions are squashed for space savings
unsigned int ata_bsy(void)
unsigned int ata_rdy(void)
unsigned int ata_err(void)
{
unsigned char ata_byte_read;
avr_databus_in;
delay_us(1);
PORT_ATA_IO_CNTL = ATA_IO_STATUS;
PORT_ATA_IO_CNTL &= ~ATA_DIOR;
delay_us(1);
ata_byte_read = PORT_ATA_DATA_L_IN;
PORT_ATA_IO_CNTL |= ATA_DIOR;
PORT_ATA_IO_CNTL = ATA_IO_HIZ;
if(ata_byte_read & ATA_STAT_BSY)
if(ata_byte_read & ATA_STAT_RDY)
if(ata_byte_read & ATA_STAT_ERR)
return 1;
else
return 0;
}
//End of squashed functions
void ata_hard_reset(void)
{
avr_databus_in;
PORT_ATA_IO_CNTL = ATA_IO_HIZ;
PORT_ATA_IO_CNTL &= ~ATA_RESET;
5 VDC. However, the larger 3.5″ drives
need 12 VDC in addition to the 5 VDC.
The original spin of the hard drive con-
troller used a 2-mm, 44-pin hard drive
I/O attachment point. The extra four
pins on the 2-mm connector provided
5 VDC and ground for the 2.5″ drives
right at the hard drive I/O connector. In
this spin, the 44-pin, 2-mm pin set is
replaced with the standard 40-pin 0.1″
pin set, and there isn’t a power supply
outlet at the hard drive I/O connector.
The hard drive controller is equipped
with a standard 4-pin floppy drive
power plug. As you might have fig-
ured out, the inclusion of a standard
PC power connector on the hard
drive controller allows you to power
the 3.5″ drive and the hard drive con-
troller’s electronics from a common
off-the-shelf PC power supply.
If the 2.5″ drives are used, you’ll
have to provide an attachment to sup-
ply power to the extra I/O-based power
pins on the drive. That’s where the
2.5″ to 3.5″ drive I/O adapters come in.
The adapters I purchased have a 3.5″
drive power connector that has only
the 5-VDC lines tapped into the 44-pin,
2-mm drive connector. The drive con-
verter board allows you to use the
smaller 2.5″ drives with the standard
40-pin 0.1″ cables and a PC power
supply. Although using a commodity
power supply is the easiest way to go,
any other suitable power supply
method will work just as well. Photo
2 is a shot of an Hitachi 2.5″ drive and
its associated converter board attached
to the ATA hard drive controller.
THE FIRMWARE
I wanted the ATA hard drive con-
troller to be capable of interfacing to
any standard ATA device. With that
design requirement mind, I wrote the
hard drive controller’s AVR firmware
with ImageCraft’s ICCAVR C compil-
er and guidance from the ATA-3 speci-
fication. What I ended up with was a
basic set of routines that allows you
to exercise the standard ATA com-
mand set, query the hard drive register
set, and exchange data with the
attached ATA hard drive.
As soon as I had access to the hard
drive’s register set and data, I set out
to write code to move the data that
www.circuitcellar.com
(Continued)
4
Issue 150
January 2003
CIRCUIT CELLAR
®
was harvested from the hard drive to
the outside world. The first logical
choice of data transport was a serial
port. After thinking it over, I decided
that an Ethernet interface would be an
excellent way to move data in and out
of the hard drive controller. The
Ethernet port would allow the hard
drive controller to be networked and
provide a high-speed data connection
for transfer rates beyond the capabili-
ties of a serial port. In either case (seri-
al or Ethernet), you could use any of
the Visual (e.g., Visual Basic, Visual C)
or Borland compilers to build an
embedded or PC interface to the ATA
hard drive controller.
The first order of business as I start-
ed to develop the AVR firmware was
to define all of the functions that
would run against the hard drive.
With respect to the software, a hard
drive looks like an 8- or 16-bit I/O
port that leads to an internal register
set. Register I/O is normally
achieved in 8-bit mode, while data
transfers are typically performed in
16-bit operations.
If you review Figure 1, you’ll see
that a 16-bit data bus is pinned out on
the 40-pin hard drive I/O connector.
The data bus signals are supported by
a set of I/O read and write signals.
Access to the internal hard drive regis-
ter set is accomplished using the I/O
read/write signals and data bus signals
in conjunction with the address and
Listing 2—
Continued
delay_ms(10);
PORT_ATA_IO_CNTL |= ATA_RESET;
}
void ata_select_device(unsigned char device)
{
PORT_ATA_IO_CNTL = ATA_IO_DEVICE_HEAD;
switch (device)
{
case 0x00:
ata_write_byte(ATA_DH_DEV0);
break;
case 0x01:
ata_write_byte(ATA_DH_DEV1);
break;
default:
ata_write_byte(ATA_DH_DEV0);
break;
}
}
void ata_send_cmd(unsigned char atacmd)
{
PORT_ATA_IO_CNTL = ATA_IO_CMD;
avr_databus_out;
PORT_ATA_DATA_L_OUT = atacmd;
ata_write_pulse;
PORT_ATA_IO_CNTL = ATA_IO_HIZ;
avr_databus_in;
}
select signals found on the 40-pin
hard drive I/O connector. The control
block is the core set of hard drive
internal registers. Listing 1 is my def-
inition of how the control block reg-
isters are addressed.
If you take a close look at the con-
trol block register definitions in
Listing 1, you’ll notice that the
basic components (in register form)
of addressing data on a hard drive
are represented. Cylinder head sec-
tor (CHS) addressing is implied in
the control block register names;
however, in the ATA hard drive
controller firmware, I’ll use these
Word
0
F/V
Identify device information
General configuration of bit-significant information:
15 0 = ATA device 1 = ATAPI device
14 Obsolete
13 Obsolete
12 Obsolete
11 Obsolete
10 Obsolete
9 Obsolete
8 Obsolete
7 1 = Removable media device
6 1 = Not removable controller and/or device
5 Obsolete
4 Obsolete
3 Obsolete
2 Obsolete
1 Obsolete
0 Reserved
Word
1
2
3
4
5
6
7–9
10–19
20
21
22
23–26
27–46
47
F/V
F
R
F
X
X
F
X
F
X
X
F
F
F
X
R
F
R
Identify device information
Number of logical cylinders
Reserved
Number of logical heads
Obsolete
Obsolete
Number of logical sectors per logical track
Vendor specific
Serial number (20 ASCII characters)
Obsolete
Obsolete
Number of vendor-specific bytes available on read/write long commands
Firmware revision (eight ASCII characters)
Model number (40 ASCII characters)
15–8 Vendor specific
7–0 00h = Reserved
01h–FFh = Maximum number of sectors that can be transferred
per interrupt on read/write multiple commands
Reserved
F
F
F
F
F
F
F
F
F
F
F
F
F
F
F
F
48
Table 1—
If you like to write code that parses data, then writing ATA hard drive code will keep you happy (and busy) for days. The data in Photo 3 was culled from this table of
words spoken by the little Hitachi DK211A-54.
F
represents a fixed value,
V
represents a variable value,
X
represents a vendor-specific value, and
R
represents a reserved value.
www.circuitcellar.com
CIRCUIT CELLAR
®
Issue 150
January 2003
5
Zgłoś jeśli naruszono regulamin