📄 ide.c
字号:
/*********************************************************************************************
* File: ide.c
* Author: embest
* Desc: test board's IDE interface
* History:
*********************************************************************************************/
/*--- include files ---*/
#include "44b.h"
#include "44blib.h"
#include "ide.h"
/* Base Address
HEX BINARY DESCRIPTION
1FX 0001 1111 XXXX Primary Command Registers
3FX 0011 1111 XXXX Primary Control Registers
17X 0001 0111 XXXX Alternate Command Registers
37X 0011 0111 XXXX Alternate Control Registers
^
|
+--- Address bit A7
*/
/*
* new board
*/
#define ADDR_COMMAND 0x02400020
#define ADDR_CONTROL 0x02400010
/*
* s3cev40 board
*/
//#define ADDR_COMMAND 0x020C0002
//#define ADDR_CONTROL 0x020C0004
/*
* other
*/
//#define ADDR_COMMAND 0x04000002
//#define ADDR_CONTROL 0x04000004
/* Registers
+----+------+------+---+---+---+----------------+---------------+
|Addr|-CS1FX|-CS3FX|SA2|SA1|SA0| Read (-IOR) | Write (-IOW) |
+----+------+------+---+---+---+----------------+---------------+-----------+
| | 0 | 0 | X | X | X | ILLEGAL | ILLEGAL | <--+ |
| | 1 | 1 | X | X | X | High Impedance | Not Used | Control |
|3FX | 1 | 0 | 0 | X | X | High Impedance | Not Used | Block |
|3FX | 1 | 0 | 1 | 0 | X | High Impedance | Not Used | Registers |
|3F6 | 1 | 0 | 1 | 1 | 0 | Altern Status | Device Control| | |
|3F7 | 1 | 0 | 1 | 1 | 1 | Drive Address | Not Used | <--+ |
+----+------+------+---+---+---+----------------+---------------+-----------+
|1F0 | 0 | 1 | 0 | 0 | 0 | Data Port | Data Port | <--+ |
|1F1 | 0 | 1 | 0 | 0 | 1 | Error Register | Precomp | | |
|1F2 | 0 | 1 | 0 | 1 | 0 | Sector Count | Sector Count | Command |
|1F3 | 0 | 1 | 0 | 1 | 1 | Sector Number | Sector Number | Block |
|1F4 | 0 | 1 | 1 | 0 | 0 | Cylinder Low | Cylinder Low | Registers |
|1F5 | 0 | 1 | 1 | 0 | 1 | Cylinder High | Cylinder High | | |
|1F6 | 0 | 1 | 1 | 1 | 0 | Drive / Head | Drive / Head | | |
|1F7 | 0 | 1 | 1 | 1 | 1 | Status | Command | <--+ |
+----+------+------+---+---+---+----------------+---------------+-----------+
At power-up or after reset, the Command Block Registers are initialized to the following values:
REGISTER VALUE
1F1 Error : 01
1F2 Sector Count : 01
1F3 Sector Number : 01
1F4 Cylinder Low : 00
1F5 Cylinder High : 00
1F6 Drive / Head : 00
*/
/*
* new board
*/
#define REG_ADDR(x) (x<<1)
/*
On S3CEV40 board
S3C44B0X IDE
(A4-A5) -> (A0-A1)
A3 -> A2
so that convert it.
*/
/*
* s3cev40 board
*/
//#define REG_ADDR(x) (((x & 3) << 4) | ((x & 4) << 1))
#define HIGH_IMPEDANCE REG_ADDR(0)
#define ALTERN_STATUS REG_ADDR(6)
#define DRIVE_ADDRESS REG_ADDR(7)
#define DEVICE_CONTROL REG_ADDR(6)
#define DATA_PORT REG_ADDR(0)
#define ERROR_REGISTER REG_ADDR(1)
#define SECTOR_COUNT REG_ADDR(2)
#define SECTOR_NUMBER REG_ADDR(3)
#define CYLINDER_LOW REG_ADDR(4)
#define CYLINDER_HIGH REG_ADDR(5)
#define DRIVE_HEAD REG_ADDR(6)
#define STATUS REG_ADDR(7)
#define PRECOMP REG_ADDR(1)
#define COMMAND REG_ADDR(7)
/* Error Register
+-----+--------+-------------------------------------------------------------+
| BIT | Mnemon | Description |
+-----+--------+-------------------------------------------------------------+
| 7 | BBK | Bad block mark detected in the requested sector's ID field |
| 6 | UNC | Uncorrectable data error encountered |
| 5 | | Not used |
| 4 | IDNF | Requested sector's ID field not found |
| 3 | | Not used |
| 2 | ABRT | Command aborted due to drive status error or invalid command|
| 1 | TK0NF | Track 0 not found during execution of Recalibrate command |
| 0 | AMNF | Data address mark not found after correct ID field found |
+-----+--------+-------------------------------------------------------------+
*/
#define AMNF 0x1
#define TKONF 0x2
#define ABRT 0x4
#define IDNF 0x10
#define UNC 0x40
#define BBK 0x80
/* Drive/Head Register
+-----+----------+---------------------------------------------------------+
| BIT | Mnemonic | Description |
+-----+----------+---------------------------------------------------------+
| 7 | Reserved | Always one. |
| 6 | Reserved | Always zero. |
| 5 | Reserved | Always one. |
| 4 | DRV | 0 to select primary drive, 1 to select secondary drive. |
| 3 | HS3 | MSB of head number. |
| 2 | HS2 | |
| 1 | HS1 | |
| 0 | HS0 | LSB of head number. |
+-----+----------+---------------------------------------------------------+
*/
#define HS0 0x1
#define HS1 0x2
#define HS2 0x4
#define HS3 0x8
#define DRV 0x10
#define REV5 0x20
#define LBA 0x40
#define REV7 0x80
/* Status Register
+-----+----------+----------------------------------------------------------+
| BIT | Mnemonic | Description |
+-----+----------+----------------------------------------------------------+
| 7 | BUSY | Busy bit. Set by the controller logic of the drive when |
| | | ever the drive has access to and the host is locked out |
| | | of the Command Block Registers. Set under the following |
| | | conditions: |
| | | o Within 400 nsec after the negation of RESET or after |
| | | SRST is set in the Device Control Register. After a |
| | | reset it is recomended that BUSY be set no more than |
| | | 30 seconds. |
| | | o Within 400 nsec of a host write to the Command |
| | | Register with a Recalibrate, Read Long, Read Buffer, |
| | | Read, Read Verify, Initialize Drive Parameters, Seek |
| | | Identify Drive, or Execute Drive Diagnostic command. |
| | | o Within 5 microseconds following the transfer of 512 |
| | | bytes of data during the execution of a Write, Write |
| | | Buffer or Format Track command; or 512 bytes of data |
| | | and the appropriate number of ECC bytes during the |
| | | execution of a Write Long command. |
| | | When BUSY is set no Command Block Register can be |
| | | written too and a read of any Command Block Register |
| | | returns the contents of the Status Register. |
| | | |
| 6 | DRDY | Drive Ready bit. Indicates that the drive is ready to |
| | | accept commands. When and error occurs, this bit stays |
| | | unchanged until the host reads the Status Register then |
| | | again indicates that hte drive is ready. On power up, |
| | | this bit should be cleared and should remain cleared |
| | | until the drive is up to speed and ready to accept a |
| | | command. |
| | | |
| 5 | DWF | Drive Write Fault bit. When an error occurs, this bit |
| | | remains unchanged until the host reads the Status |
| | | Register, then again indicates the current write fault |
| | | status. |
| | | |
| 4 | DSC | Drive Seek Complete bit. This bit is set when a seek |
| | | operation is complete and the heads are settled over a |
| | | track. When an error occurs, this bit remains unchanged |
| | | until the host reads the Status Register, then again it |
| | | indicates the current seek complete status. |
| | | |
| 3 | DRQ | Data Request bit. When set it indicates that the drive |
| | | is ready to transfer a word or byte of data between the |
| | | host and the data port. |
| | | |
| 2 | CORR | Corrected Data bit. When a correctable data error has |
| | | been encountered and the data has been corrected, this |
| | | bit is set. This condition does not terminate a multi |
| | | sector read operation. |
| | | |
| 1 | INDEX | Index bit. Set when the index mark is detected once per |
| | | disk revolution. |
| | | |
| 0 | ERROR | Error bit. When set indicates that the previous command |
| | | ended in an error. The other bits in the Error Register |
| | | and Status Register contain additional information about |
| | | the cause of the error. |
+-----+----------+----------------------------------------------------------+
*/
#define ERROR 0x1
#define INDEX 0x2
#define CORR 0x4
#define DRQ 0x8
#define DSC 0x10
#define DWF 0x20
#define DRDY 0x40
#define BUSY 0x80
/* Command Register
+--------+---------------------------------+-----------------+
| Command| Command Description | Parameters Used |
| Code | | PC SC SN CY DH |
+--------+---------------------------------+-----------------+
| 98h @ | Check Power Mode | V D |
| E5h @ | Check Power Mode (same as 98h) | V D |
| 90h | Execute Drive Diagnostic | D+ |
| 50h | Format Track | V V |
| ECh @ | Identify Drive | D |
| 97h @ | Idle | V D |
| E3h @ | Idle (same as 97h) | V D |
| 95h @ | Idle Immediate | D |
| E1h @ | Idle Immadiate (same as 95h) | D |
| 91h | Initialize Drive Parameters | V V |
| E4h @ | Read Buffer | D |
| C8h @ | Read DMA With Retry | >> Unknown << |
| C9h @ | Read DMA | >> Unknown << |
| C4h @ | Read Multiple | V V V V |
| 20h | Read Sectors With Retry | V V V V |
| 21h | Read Sectors | V V V V |
| 22h | Read Long With Retry | V V V V |
| 23h | Read Long | V V V V |
| 40h | Read Verify Sectors With Retry | V V V V |
| 41h | Read Verify Sectors | V V V V |
| 1Xh | Recalibrate | D |
| 7Xh | Seek | V V |
| EFh @ | Set Features | V D |
| C6h @ | Set Multiple Mode | V D |
| 99h @ | Set Sleep Mode | D |
| E6h @ | Set Sleep Mode (same as 99h) | D |
| 96h @ | Standby | V D |
| E2h @ | Standby (same as 96h) | V D |
| 94h @ | Standby Immediate | D |
| E0h @ | Standby Immediate (same as 94h) | D |
| 8Xh | Vendor Unique | >> Unknown << |
| 9Ah | Vendor Unique | >> Unknown << |
| C0h | Vendor Unique | >> Unknown << |
| C1h | Vendor Unique | >> Unknown << |
| C2h | Vendor Unique | >> Unknown << |
| C3h | Vendor Unique | >> Unknown << |
| F5h | Vendor Unique | >> Unknown << |
| F6h | Vendor Unique | >> Unknown << |
| F7h | Vendor Unique | >> Unknown << |
| F8h | Vendor Unique | >> Unknown << |
| F9h | Vendor Unique | >> Unknown << |
| FAh | Vendor Unique | >> Unknown << |
| FBh | Vendor Unique | >> Unknown << |
| FCh | Vendor Unique | >> Unknown << |
| FDh | Vendor Unique | >> Unknown << |
| FEh | Vendor Unique | >> Unknown << |
| FFh | Vendor Unique | >> Unknown << |
| E8h @ | Write Buffer | D |
| CAh @ | Write DMA With Retry | >> Unknown << |
| CBh @ | Write DMA | >> Unknown << |
| C5h @ | Write Multiple | V V V V |
| E9h @ | Write Same | >> Unknown << |
| 30h | Write Sectors With Retry | V V V V |
| 31h | Write Sectors | V V V V |
| 32h | Write Long With Retry | V V V V |
| 33h | Write Long | V V V V |
| 3Ch @ | Write Verify | V V V V |
+--------+---------------------------------+-----------------+
KEY FOR SYMBOLS IN ABOVE TABLE:
PC Register 1F1: Write Precompensation
SC Register 1F2: Sector Count
SN Register 1F3: Sector Number
CY Register 1F4+1F5: Cylinder low + high
DH Register 1F6: Drive / Head
@ These commands are optional and may not be supported by some drives.
D Only DRIVE parameter is valid, HEAD parameter is ignored.
D+ Both drives execute this command regardless of the DRIVE parameter.
V Indicates that the register contains a valid paramterer.
*/
#define CHECK_POWER_MODE1 0x98
#define CHECK_POWER_MODE2 0xE5
#define EXECUTE_DRIVE_DIAGNOSTIC 0x90
#define FORMAT_TRACK 0x50
#define IDENTIFY_DRIVE 0xEC
#define IDLE1 0x97
#define IDLE2 0xE3
#define IDLE_IMMEDIATE1 0x95
#define IDLE_IMMADIATE2 0xE1
#define INITIALIZE_DRIVE_PARAMETERS 0x91
#define READ_BUFFER 0xE4
#define READ_DMA_WITH_RETRY 0xC8
#define READ_DMA 0xC9
#define READ_MULTIPLE 0xC4
#define READ_SECTORS_WITH_RETRY 0x20
#define READ_SECTORS 0x21
#define READ_LONG_WITH_RETRY 0x22
#define READ_LONG 0x23
#define READ_VERIFY_SECTORS_WITH_RETRY 0x40
#define READ_VERIFY_SECTORS 0x41
#define RECALIBRATE 0x1F
#define SEEK 0x7F
#define SET_FEATURES 0xEF
#define SET_MULTIPLE_MODE 0xC6
#define SET_SLEEP_MODE1 0x99
#define SET_SLEEP_MODE2 0xE6
#define STANDBY1 0x96
#define STANDBY2 0xE2
#define STANDBY_IMMEDIATE1 0x94
#define STANDBY_IMMEDIATE2 0xE0
#define WRITE_BUFFER 0xE8
#define WRITE_DMA_WITH_RETRY 0xCA
#define WRITE_DMA 0xCB
#define WRITE_MULTIPLE 0xC5
#define WRITE_SAME 0xE9
#define WRITE_SECTORS_WITH_RETRY 0x30
#define WRITE_SECTORS 0x31
#define WRITE_LONG_WITH_RETRY 0x32
#define WRITE_LONG 0x33
#define WRITE_VERIFY 0x3C
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -