1. MCBtec Mas información en
www.mcbtec.com
CONTROL DISCO DURO MEDIANTE
UN MICROCONTROLADOR
INDICE:
1. Introducción.
2. Estructura física del HD.
3. Modos de trabajo del BUS ATA.
4. Conexión al COP8CCR.
5. Registros del BUS ATA-IDE.
6. Programación básica del BUS ATA-IDE.
1. Introducción.
En este texto se describe como conectar un HD a un microcontrolador. El
microcontrolador seleccionado, es el COP8CCR pero podemos fácilmente adaptarlo a
cualquier micro, ya que las patillas utilizadas solo son líneas de entrada/ salida.
La única parte del circuito no descrita en este texto, es la alimentación del HD ya
que los consumos dependen de cada disco duro en particular. De todas formas lo mejor
es utilizar una vieja fuente de alimentación de PC, que ya tiene los conectores y esta
preparada para poder conectarse al HD de forma inmediata.
2. Estructura física del HD.
El disco duro esta internamente constituido por C cilindros con S sectores por
cilindro y H cabezas ( mirar gráfico).
2. Cada sector tiene 512 bytes de información (256 words), lo que implica que, por
ejemplo, un HD con 500 cilindros, 17 sectores por cilindro y 16 cabezas tendrá una
capacidad de 500*17*512*16=69.6Mbytes.
3. Modos de trabajo del bus ATA.
Para poder leer y grabar en él, los HD dispone de dos modos de acceso:
• Modo PIO: En este modo de trabajo es la CPU del ordenador la que gestiona
totalmente la transferencia de datos. Hay 6 modos de trabajo cuya diferencia esta
en la velocidad de transmisión:
Modo PIO tiempo de ciclo velocidad transmisión Estándar
0 600 ns 3.3 MB/s ATA
1 383 ns 5.2 MB/s ATA
2 240 ns 8.3 MB/s ATA
3 180 ns 11.1 MB/s ATA-2 usa IORDY
4 120 ns 16.6 MB/s ATA-2 usa IORDY
5 90 ns 22.2 MB/s Vaporware
• Modo DMA: En este modo los datos son transferidos directamente por el HD a
la memoria sin utilizar tiempo de CPU.
Como las mayoría de los microcontroladores no tiene controlador de DMA nos
centraremos en el control del HD utilizando el protocolo de transmisión PIO.
4. Conexión al COP8CCR.
La función de estas líneas y su conexión con el COP8CCR es la siguiente:
Conexión Señal Función
D0 -RESET Señal de Reset desde la CPU.
B0..7/L0..L7 DD0..7,DD8..15 Líneas de datos de I/O.
D3, D4, D5 A0, A1, A2 Líneas de direcciones.
D6, D7 -CS3FX, -CS1FX Líneas de selección de registros de control/ comando.
---- -IOCS16 Señal que activa indica que se puede acceder al HD para leer
datos en 16bits.
D2 -DIOR Un flanco de bajada habilita al PC a leer el dato del registro
seleccionado.
D1 -DIOW Un flanco de subida habilita al PC a escribir en el registro
seleccionado.
---- -IORDY Señal triestado que inserta tiempos de espera en el bus.
---- INTRQ Señal que utiliza el HD para interrumpir al PC.
0v CSEL Señal que se utiliza para sincronizar/ diferenciar los dos
drivers del cable.
---- -DMACK DMA concedida.
---- DMARQ Petición de DMA
---- -PDIAG Con esta línea el HD esclavo le indica al maestro que ha
realiza tu diagnostico interno.
---- -DASP Tiene dos funciones:
Si el HD es esclavo esta línea le indica al maestro al principio
que esta.
Si no se utiliza con un driver para controlar el LED del HD.
2
3. En el siguiente diagrama podemos ver las conexiones necesarias para poder
trabajar con el disco duro desde el COP8CCR . El conector de alimentación del disco
duro no se representa aquí, las líneas de alimentación son +12v, +5v y GND.
5. Registros del BUS ATA-IDE.
El control del disco duro se realiza mediante la utilización de varios registros
internos. Por ejemplo, si queremos leer un sector haríamos lo siguiente:
1. Comprobaríamos, mediante la lectura del registro de estado ( Status Register SR
), que el disco duro esta preparado para trabajar comprobando los bits BUSY y
DRQ.
2. Metemos en los registros SN, CL, CH, DH ( el registro DH tiene que tener el bit
6 a 1 para trabajar en modo LBA) y SC el sector que queremos leer.
3. Escribimos en el registro de comandos CR la instrucción de lectura que es 20H.
4. Leemos el registro de datos 256 veces.
Los registros del HD se dividen en dos grupos principales; Registros de
comandos y registros de control. La selección entre un grupo y otro se realiza mediante
las líneas –CS1FX y –CS3FX según queramos leer o escribir. En la tabla siguiente
vemos la operación según su valor:
3
4. -CS1FX -CS3FX DA2 DA1 DA0 -DIOR -DIOW PUERTO
0 0 X X X No operación No operación --
1 1 X X X Dirección no valida Dirección no valida --
0 1 X X X Registros de Comandos Registros de Comandos --
1 0 X X X Registros de Control Registros de Control --
En la siguiente tabla vemos el valor de cada una de las líneas para seleccionar
los registros del grupo Registros de Comandos y el valor que tendríamos que poner en
el puerto D del COP8CCR.
-CS1FX -CS3FX DA2 DA1 DA0 -DIOR -DIOW PUERTO D
0 1 0 0 0 Registro de Datos(DR) Registro de 47H
DD0..DD15 Datos(DR)
DD0..DD15
0 1 0 0 1 Registro de Error(ER) Registro de 4FH
Características(FR)
0 1 0 1 0 Contador de Contador de 57H
Sector(SC) Sector(SC)
Numero de sectores Numero sectores a
transferido. transferir.
0=256 sectores. 0=256 sectores.
Al inicio contiene el
Nº sectores
0 1 0 1 1 Numero de Sector(SN) Numero de Sector(SN) 5FH
Sector actual. Sector inicial a
LBA bit 7..0 bloque transferir.
lógico
0 1 1 0 0 Parte baja del Parte baja del 67H
Cilindro(CL) Cilindro(CL)
Parte baja actual del Pone parte baja del
cilindro cilindro
LBA bit15..8 bloque LBA bit15..8 bloque
lógico lógico
0 1 1 0 1 Parte alta del Parte alta del 6FH
Cilindro(CH) Cilindro(CH)
Parte alta actual del Parte alta actual del
cilindro cilindro
LBA bit23..16 bloque LBA bit23..16 bloque
lógico lógico
0 1 1 1 0 Disco/ Cabeza(DH) Disposi./ cabezas(DH) 77H
0 1 1 1 1 Registro de Registro 7FH
estado(SR) comandos(CR)
En la siguiente tabla vemos el valor de cada una de las líneas para seleccionar
los registros del grupo Registros de Control y el valor que tendríamos que poner en el
puerto D del COP8CCR.
-CS1FX -CS3FX DA2 DA1 DA0 -DIOR -DIOW PUERTO
1 0 0 X X Bus en alta No utilizado --
impedancia
1 0 1 0 X Bus en alta No utilizado --
impedancia
1 0 1 1 0 Registro estado Registro control B7H
alternativo (ASR) HD(DCR)(6)
Contiene misma
información que el
4
5. registro de estado
1F7H
1 0 1 1 1 Registro dirección del No utilizado BFH
HD(DAR)
Vamos a ver más en profundidad el significado de cada uno de los bits de los
registros del HD:
Registro de Error: Cuando el bit ERR del registro de estado vale 1, leemos este
registro para identificar el tipo de error.
7 6 5 4 3 2 1 0
BBK UNC MC IDNF MCR ABRT TKONF AMNF
El significado de cada bit es el siguiente:
• BBK: Indica una marca errónea en el bloque en el campo ID del sector buscado.
• UNC: Error en los datos.
• IDNF: No se puede encontrar el campo ID del sector buscado.
• ABRT: El comando es invalido o se ha abortado por un error en el disco.
• TK0NF: El track 0 no ha sido encontrado.
• AMNF: La marca de dirección del dato no ha sido encontrada después de
encontrar el campo ID correcto.
• MC: Bit reservado para removable-media drives.
Cuando el drive es reseteado o se ejecuta un comando de diagnostico, este
registro contiene el diagnostico, cuyos posibles valores son:
01H: No hay error.
02H: Error de formateo del disco.
03H: Error en el buffer de sectores.
04H: Error en el circuito ECC.
05H: Error en el micro de control.
8XH: Error en el test del disco esclavo.
Registro de características: Cuando en el registro de comando ejecutamos EFH
(Features command). En este registro ponemos la característica que queremos que tenga
el HD (ver características de cada disco duro en particular) según la tabla siguiente:
Comando Característica
01H Habilita transferencia en 8 bits.
02H Activa la cache de escritura.
03H Pone el modo de DMA según el valor del registro de contador de sectores
00000-000: Transferencia de bloques (por defecto).
00010-0XX: DMA mode XX.
00100-000: DMA multiword mode 0.
33H Desactiva RETRIES.
44H Usa la máxima longitud de la ECC.
54H Pone el segmento de la cache al valor almacenado en el Contador de Sectores.
55H Desactiva la característica leer look-ahead.
66H Usa las características actuales por defecto (hasta un reset o apagado).
77H Desactiva ECC.
5
6. 81H Desactiva transferencia datos en 8 bits.(por defecto).
82H Desactiva la cache de escritura.
88H Activa la ECC.(por defecto).
99H Activa RETRIES.(por defecto).
AAH Activa la característica leer look-ahead.(por defecto).
BBH Aplica 4 bits de ECC en la lectura/ escritura de comandos largos.
CCH Enable reverting to power-on defaults
Registro de Disco/Cabeza: Este registro contiene información sobre el número
de disco en el bus y la cabeza que esta actualmente seleccionada.
7 6 5 4 3 2 1 0
1 LBA 1 DRV HEAD3 HEAD2 HEAD1 HEAD0
El significado de cada bit es el siguiente:
• LBA: Si ponemos el bit a 1 seleccionamos el modo de transmisión por bloques.
• DRV: Este bit lo pone el HD y si vale 0 es el disco maestro y si 1 es el disco
esclavo.
• HEAD: Cabeza seleccionada. después del reset indica el numero de cabezas que
tiene el HD.
Registro de Estado: Contiene tanto el estado del disco como el estado de la
controladora. leer el registro baja el banderín de interrupción.
7 6 5 4 3 2 1 0
BSY DRDY DWF DSC DRQ CORR IDX ERR
El significado de cada bit es el siguiente:
• BSY: Bit de BUSY, este es puesto a uno por la controladora mientras esta
ejecutando un comando o se produce un reset.
• DRDY: Este bit se pone a 0 después de un reset y continua en este estado hasta
que el disco este preparado para recibir un comando.
• DWF: Un uno indica error de escritura. Permanecerá en 1 hasta que leamos el
registro de estado.
• DSC: Permanece a 1 mientras el disco no este posicionado.
• DRQ: Se pone a 1 cuando el disco esta preparado para enviar/ recibir un dato.
• CORR: Este bit se pone a 1 si se ha encontrado un error de datos y se a podido
corregir.
• IDX: Tiene normalmente un cero salvo una vez por revolución del disco.
• ERR: Un 1 indica que ha habido un error.
Registro de Commandos: Antes de escribir un comando en este registro hay que
ver que el bit BSY este a 0 y que los registro necesarios para ejecutar este comando
tengan los valores adecuados.
Registro de Control: Contiene los siguientes bits.
6
7. 7 6 5 4 3 2 1 0
X X X X 1 SRSTT nIEN 0
El significado de cada bit es el siguiente:
• nIEN: Cuando se pone un 0 la señal de interrupción INTRQ es activada.
• SRST: Cuando se pone a 1 el disco se resetea. cuando es 0 el disco esta
utilizable.
Registro dirección del HD: Este registro contiene el disco/ cabeza seleccionado .
7 6 5 4 3 2 1 0
HiZ nWTG nHS3 nHS2 nHS1 nHS0 nDS1 nDS0
El significado de cada bit es el siguiente:
• nWTG: Este bit se pone a 1 durante un comando de escritura.
• nHS3..nHS0: Es el NOT de la cabeza seleccionada.
• nDS1: Un 0 indica que esta seleccionado el drive 1 (esclavo).
• nDS0: Un 0 indica que esta seleccionado el driver 0 (maestro).
El protocolo para acceder a los registros es el siguiente:
Función Descripción del proceso.
LEER REGISTRO Ponemos en A0..A2, -CS1FX, -CS3FX la dirección del registro a leer.
Pulso de bajada en –DIOR.
Leemos el bus DD0..DD15 (0..7 si es un registro).
Pulso de subida en –DIOR.
GRABA REGISTRO Ponemos en A0..A2, -CS1FX, -CS3FX la dirección del registro a grabar.
Ponemos en DD0..DD15 el valor a grabar (0..7 si es un registro).
Pulso de bajada en –DIOW.
Pulso de subida en –DIOW.
6. Programación básica del BUS ATA-IDE con COP8CCR9.
El protocolo básico para controlar la información almacenada en el disco duro
desde el microcontrolador utilizando el acceso al disco en modo LBA es la siguiente:
Función Descripción.
RESET Línea Reset (D0) a 0.
Esperamos 8 ms
Línea Reset (D0) a 1.
Comprobamos SR (7FH) hasta que valga 50H.
Quitamos Interrupciones Poniendo DCR (B7H) el valor 02H.
LEER SECTOR Comprobamos SR (7FH) sea 50H (BUSY=0 DRQ=0).
Metemos SN, CL, CH, DH (con bit 6 a 1 para LBA) y SC.
Ponemos CR (7FH) la instrucción de lectura 20H
Leemos el ASR (B7H) y descartamos lo que leemos.
Leemos SR (7FH) hasta que DRQ=1.
Leemos los 256 words del buffer.
GRABA SECTOR Comprobamos SR (7FH) sea 50H (BUSY=0 DRQ=0).
Metemos SN, CL, CH, DH (con bit 6 a 1 para LBA) y SC.
7
8. Ponemos CR (7FH) la instrucción de escritura 30H
Leemos el ASR (B7H) y descartamos lo que leemos.
Leemos SR (7FH) hasta que DRQ=1.
escribimos los 256 words del buffer.
Comprobamos SR (7FH) que DRQ=0.
Para implementar estos protocolos en el COP8CCR9 tendremos que crear una
serie de variables en las que almacenar temporalmente los valores de los registros. Esta
variables son:
DHREG = H'00:BYTE ;REGISTRO DISCO/CABEZA
CHREG = H'01:BYTE ;PARTE BAJA DEL CILINDRO
CLREG = H'02:BYTE ;PARTE ALTA DEL CILINDRO
SNREG = H'03:BYTE ;NUMERO DE SECTOR
SCREG = H'04:BYTE ;CONTADOR DE SECTORES
De las rutinas listadas en la a continuación, las importantes son:
• INICIOHD: Una llamada a esta rutina inicializa el disco duro a nivel de
hardware.
• LEESECTOR: Almacena en una tabla en memoria cuyo inicio es la dirección
#TABINI los 256 word del sector direccionado por el valor almacenado en los
registros DHREG, CHREG, CLREG, SNREG y SCREG ( en la tabla de
direcciónamiento de registros aparece la asignación de bits de cada registro en la
dirección lógica LBA) .
• GRABSECTOR: Almacena en el sector direccionado por los registros
DHREG, CHREG, CLREG, SNREG y SCREG los valores almacenados en una
tabla en memoria cuyo inicio es la dirección #TABINI.
Estas rutinas aplicadas al COP8CCR serian las siguientes:
;---------------------------------------------------------------------
; RUTINAS BASICAS DE CONTROL DEL HD
;---------------------------------------------------------------------
;RESETEA HD POR LA LINEA D0 DEL PORTD, USA 0F0,0F1.
RESETHD: RBIT 0,PORTD ;Línea RESET(D0) a 0
LD 0F0,#H'FE ;Espera
RSEHD01: DRSZ 0F0
JP RSEHD01
SBIT 0,PORTD ;Línea RESET(D0) a 1
LD 0F1,#H'20 ;Espera 8 ms Antes leer SR
RSEHD03: LD 0F0,#H'FE
RSEHD02: DRSZ 0F0
JP RSEHD02
DRSZ 0F1
JP RSEHD03
RET
;LEE EL REGISTRO ASR DEL HD Y METE EL VALOR EN A.
LEEASR: LD PORTD,#H'B7 ;Pone dirección del registro ASR
RBIT 2,PORTD ;Línea –DIOR a 0
LD A,PORTBP ;A contiene el valor del registro
8
9. SBIT 2,PORTD ;Línea –DIOR a 1
RET
;TESTEA QUE LOS BITS BSY=0 Y DRDY=1 DEL REGISTRO DE ESTADO, USA A.
TSTINI: LD PORTD,#H'7F ;Pone dirección del registro SR
RBIT 2,PORTD ;Línea –DIOR a 0
LD A,PORTBP ;A contiene el valor del registro
SBIT 2,PORTD ;Línea –DIOR a 1
IFNE A,#H'50 ;Si SR<>50H el disco duro esta ocupado
JP TSTINI
RET
;TESTEA QUE EL VALOR DEL BIT DE BSY=0 EN EL R. DE ESTADO, USA A.
TSTBSY: LD PORTD,#H'7F ;Pone dirección del registro SR
RBIT 2,PORTD ;Línea –DIOR a 0
LD A,PORTBP ;A contiene el valor del registro
SBIT 2,PORTD ;Línea –DIOR a 1
AND A,#H'80
IFNE A,#H'00 ;Si BSY=0 finaliza
JP TSTBSY
RET
;TESTEA EL BYTE DE BSY=0 Y DRQ=1 DEL R. ESTADO, USA A.
TSTDRQ: LD PORTD,#H'7F ;Pone dirección del registro SR
RBIT 2,PORTD ;Línea –DIOR a 0
LD A,PORTBP ;A contiene el valor del registro
SBIT 2,PORTD ;Línea –DIOR a 1
AND A,#H'88
IFNE A,#H'08 ;Si BSY=0 y DRQ=1 finaliza
JP TSTDRQ
RET
;LEE EL REGISTRO SELECCIONADO POR PORTD Y METE VALOR EN A.
LEEREG: RBIT 2,PORTD ;Línea –DIOR a 0
LD A,PORTBP ;A contiene el valor del registro
SBIT 2,PORTD ;Línea –DIOR a 1
RET
;ESCRIBE EN EL REGISTRO SELECCIONADO POR PORTD EL VALOR DE A.
ESCREG: LD PORTBC,#H'FF ;Pone puerto B como salida
X A,PORTBD ;PuertoB = A
RBIT 1,PORTD ;Línea –DIOW a 0
SBIT 1,PORTD ;Línea –DIOW a 1
LD PORTBC,#H'00 ;Pone puerto B como entrada
LD PORTBD,#H'00
RET
;INICIALIZA EL HD POR HARDWARE
;USA A,0F0,0F1,0FA,0FB
INICIOHD: JSRL RESETHD ;RESET HD POR HARDWARE
JSRL TSTINI ;COMPRUEBA EL BANDERIN DE BSY Y DRDY
LD PORTD,#H'B7 ;PONE DCR=$02 PARA QUITAR INTR
LD A,#H'02
JSRL ESCREG
JSRL TSTBSY
9
10. LD PORTD,#H'77 ;PONE DH=$40 PARA PONER MODO LBA
LD A,#H'40
JSRL ESCREG
JSRL TSTBSY
LD PORTD,#H'5F ;PONE SN=$00 PARA SELECCIONAR LBA=0
LD A,#H'00
JSRL ESCREG
JSRL TSTBSY
RET
;PONE LOS VALORES ALMACENADOS EN DHREG, CHREG, CLREG, SNREG, SCREG EN
EL HD
;USA A,0F0,0F1,0FA,0FB
PONDSEC: JSRL TSTBSY
LD PORTD,#H'77 ;CARGA EL REGISTRO DRIVE/HEAD
LD A,DHREG
OR A,#H'40 ;CONSERVA EL MODO LBA
JSRL ESCREG
LD PORTD,#H'6F ;CARGA CILINDRO HIG
LD A,CHREG
JSRL ESCREG
LD PORTD,#H'67 ;CARGA CILINDRO LOW
LD A,CLREG
JSRL ESCREG
LD PORTD,#H'5F ;CARGA NUMERO DE SECTOR
LD A,SNREG
JSRL ESCREG
LD PORTD,#H'57 ;CARGA NUMERO DE SECTORES A LEER
LD A,SCREG
JSRL ESCREG
RET
;LEE UN SEGMENTO DEL HD Y LO DEJA LISTO PARA LEER LOS DATOS
;USA A,0F0,0F1,0FA,0FB
LEESECT: JSRL PONDSEC
LD PORTD,#H'7F ;INSTRUCCION DE LECTURA DE SECTORES
LD A,#H'21
JSRL ESCREG
JSRL LEEASR ;ESPERA HAYAN DATOS
JSRL TSTDRQ ;LEE ESTATUS REGISTER
RET
;GRABA UN SEGMENTO EN EL HD A FALTA DE ENVIARLE LOS DATOS
;USA A,0F0,0F1,0FA,0FB
GRASECT: JSRL PONDSEC
LD PORTD,#H'7F ;INSTRUCCION DE ESCRITURA DE SECTORES
LD A,#H'31
JSRL ESCREG
JSRL LEEASR ;ESPERA HAYAN DATOS
JSRL TSTDRQ ;LEE ESTATUS REGISTER
RET
;RUTINA DE LECTURA DEL SECTOR
;USA A,B,0FA,0FB
;DHREG,CHREG,CLREG,SNREG,SCREG Contiene el sector.
LEESECTOR: JSRL LEESECT ;Selecciona registro a leer
LD B,#TABINI
10
11. LD A,#H'00
LD PORTD,#H'47 ;Selecciona registro de datos
BULEES00: RBIT 2,PORTD ;Línea –DIOR a 0
PUSH A
LD A,PORTBP
X A,[B+]
LD A,PORTLP
X A,[B+]
SILEES01: SBIT 2,PORTD ;Línea –DIOR a 0
POP A
INC A
IFEQ A,#H'00 ;Si ha leido 256 word termina
JP SILEES00
JP BULEES00
SILEES00: JSRL LEEASR ;Espera que el HD este desocupado
JSRL TSTBSY
RET
;RUTINA DE ESCRITURA DEL SECTOR
;USA A,B,0FA,0FB
GRABSECTOR: JSRL GRASECT ;Selecciona registro a grabar
LD B,#TABINI
LD A,#H'00
LD PORTD,#H'47 ;Selecciona registro de datos
LD PORTBC,#H'FF ;Puerto B y L configurado como salida
LD PORTLC,#H'FF
BUGRAS00: PUSH A
LD A,[B+]
X A,PORTBD
LD A,[B+]
X A,PORTLD
SIGRAS01: RBIT 1,PORTD ;Línea –DIOW a 0
SBIT 1,PORTD ;Línea –DIOW a 0
LD PORTBD,#H'00
LD PORTLD,#H'00
POP A
INC A
IFEQ A,#H'00 ;Si ha escrito los 256 word finaliza
JP SIGRAS00
JP BUGRAS00
SIGRAS00: LD PORTBC,#H'00 ;Puerto B y L configurado como entrada
LD PORTLC,#H'00
JSRL LEEASR ;Espera que el HD este desocupado
JSRL TSTBSY
RET
www.mcbtec.com V 1.1 - 22/01/2008
11