📄 ide_lib.lst
字号:
C51 COMPILER V7.00 IDE_LIB 01/05/2004 23:20:12 PAGE 1
C51 COMPILER V7.00, COMPILATION OF MODULE IDE_LIB
OBJECT MODULE PLACED IN IDE_LIB.OBJ
COMPILER INVOKED BY: F:\Keil\C51\BIN\C51.EXE IDE_LIB.C LARGE BROWSE INTVECTOR(0X8000) DEBUG OBJECTEXTEND TABS(2)
stmt level source
1 /*
2 Copyright (C) 2003 Bart Bilos <boombox666@yahoo.com>.
3
4 Adapted from original work by Paul Stoffregen.
5 http://www.pjrc.com/tech/8051/ide/
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
21 */
22
23 #include "IDE_LIB.h" // IDE constants and defines
24 #include "timertick.h" // timing subsystem
25 #include <stdio.h> // standard IO
26
27
28 // 8255 to IDE to Xdata mapping registers
29 xdata char ide_8255_lsb _at_ 0xE000;
30 xdata char ide_8255_msb _at_ 0xE001;
31 xdata char ide_8255_ctl _at_ 0xE002;
32 xdata char cfg_8255 _at_ 0xE003;
33
34 #define IDE_RETRIES 4
35
36
37 /* spin the HDD drive up */
38 void spinup(void) {
39 1 char i=0,status;
40 1 do {
41 2 // spinup command
42 2 ide_wr(ide_command,ide_cmd_spinup);
43 2 // wait until ide is ready
44 2 status = ide_busy(1);
45 2 // retry
46 2 i++;
47 2 } while((i < 5 ) & (status == 0xFF));
48 1 // more than 5 retries
49 1 if(i > 5)
50 1 printf("# spinup timed out #\n");
51 1 }
52 /* spin the HDD drive down */
53 void spindown(void) {
54 1 char i=0,status;
55 1 do {
C51 COMPILER V7.00 IDE_LIB 01/05/2004 23:20:12 PAGE 2
56 2 // spindown command
57 2 ide_wr(ide_command,ide_cmd_spindown);
58 2 // wait until IDE is rdy
59 2 status = ide_busy(1);
60 2 i++;
61 2 } while((i < 5 ) & (status == 0xFF));
62 1 if(i > 5)
63 1 printf("# spindown timed out #\n");
64 1 }
65
66 /* check if the IDE is busy */
67 char ide_busy(unsigned int a_timeout){
68 1 //wait for RDY bit to be set
69 1 unsigned int inittime = (unsigned int) getseconds();
70 1 int status;
71 1 do {
72 2 status = ide_rd(ide_status);
73 2 // if it takes too long bail out
74 2 if(((unsigned int) getseconds() - inittime) > a_timeout)
75 2 return 0xFF;
76 2 } while((status & 0x80) == 0x80);
77 1 return status;
78 1 }
79
80 // wait for IDE to be ready for data transfer
81 int ide_drq(unsigned int a_timeout) {
82 1 unsigned int inittime = (unsigned int) getseconds();
83 1 int status;
84 1 do {
85 2 status = ide_rd(ide_status);
86 2 // if it takes too long bail out
87 2 if(((unsigned int) getseconds() - inittime) > a_timeout)
88 2 return 0xFF;
89 2 }while(((status & 0x80) == 0x80) && ((status & 0x08) == 0x00));
90 1 return status;
91 1 }
92
93 /* reinitilise the HDD */
94 void ide_init (void) {
95 1 int status;
96 1 //select the master device
97 1 ide_wr(ide_head,0xA0);
98 1 do {
99 2 status = ide_rd(ide_status);
100 2 } while( ((status & 0x80) == 0x80) && ((status & 0x40) == 0x00) );
101 1 // write heads
102 1 ide_wr(ide_head,16);
103 1 // write sects per track
104 1 ide_wr(ide_sec_cnt,63);
105 1 // initialise
106 1 ide_wr(ide_command,ide_cmd_init);
107 1 // wait until finished
108 1 ide_busy(1);
109 1 // recalibrate
110 1 ide_wr(ide_command,ide_cmd_recal);
111 1 // wait until finished
112 1 ide_busy(1);
113 1 }
114
115 /* gets IDE error code */
116 char get_err(void){
117 1 // get error code
C51 COMPILER V7.00 IDE_LIB 01/05/2004 23:20:12 PAGE 3
118 1 char errorcode = ide_rd(ide_err);
119 1 if(errorcode == 0)
120 1 return 255;
121 1 else
122 1 return errorcode;
123 1 }
124
125
126 /*
127 reads a sector in a_buffer, at adress a_lba
128 */
129 char read_sector(unsigned long int a_lba,char * a_buffer) {
130 1 int status;
131 1 // if the return value is FF time out has occured
132 1 if(ide_busy(1) == 0xFF) {
133 2 printf("# read_sector timeout #\n");
134 2 // return error condition
135 2 return 0xFF;
136 2 }
137 1 // write adress
138 1 wr_lba(a_lba);
139 1 // read data from IDE command
140 1 ide_wr(ide_command,ide_cmd_read);
141 1 // data ready
142 1 status = ide_drq(1);
143 1 // error bit not set
144 1 if((status & 0x01) == 0x00) {
145 2 read_data(a_buffer);
146 2 return 0;
147 2 }
148 1 else {
149 2 // timed out?
150 2 if(status==0xFF){
151 3 printf("# read_sector timeout #\n");
152 3 return 0xFF;
153 3 }
154 2 else {
155 3 // nope other generic error
156 3 return get_err();
157 3 }
158 2 }
159 1 }
160
161
162 /*
163 Writes an sector to the drive
164 */
165 char write_sector(unsigned long int a_lba,char * a_buffer) {
166 1 int status;
167 1 // wait until ready
168 1 ide_busy(1);
169 1 // write dest adress to IDE
170 1 wr_lba(a_lba);
171 1 // write data to sect
172 1 ide_wr(ide_command,ide_cmd_write);
173 1 // get IDE status
174 1 status = ide_drq(1);
175 1 // if status bit is not set all is set for go
176 1 if((status & 0x01) == 0x00){
177 2 // write data
178 2 write_data(a_buffer);
179 2 // return sucess
C51 COMPILER V7.00 IDE_LIB 01/05/2004 23:20:12 PAGE 4
180 2 return 0;
181 2 }
182 1 else
183 1 // something happened
184 1 return get_err();
185 1 }
186
187 /*
188 write LBA adress
189 */
190 void wr_lba(unsigned long int a_lba) {
191 1 // write 28 bits
192 1 ide_wr(ide_head,(a_lba>>24 & 0x0F) | 0xE0);
193 1 ide_wr(ide_cyl_msb,a_lba>>16);
194 1 ide_wr(ide_cyl_lsb,a_lba>>8);
195 1 ide_wr(ide_sector,a_lba);
196 1 ide_wr(ide_sec_cnt,0x01);
197 1 }
198
199 /* get drive data and put it in the buffer */
200 void drive_id(char * a_buffer){
201 1 // drive ready?
202 1 ide_busy(1);
203 1 // request IDE data
204 1 ide_wr(ide_command,ide_cmd_id);
205 1 // wait until data ready
206 1 ide_drq(1);
207 1 // put in the buffer
208 1 read_data(a_buffer);
209 1 }
210
211 /*
212 reads sector from the IDE
213 */
214 void read_data(char * a_buffer) {
215 1 int readdata;
216 1 int i=0xFF;
217 1 do{
218 2 // read byte from IDE
219 2 readdata = ide_rd(ide_data);
220 2 // put lsb in the buffer
221 2 *a_buffer = readdata;
222 2 a_buffer++;
223 2 // put second byte in buffer
224 2 *a_buffer = (readdata>>8);
225 2 a_buffer++;
226 2 i--;
227 2 } while(i != 0);
228 1 }
229
230 /*
231 writes sector to the IDE
232 */
233 void write_data(char * a_buffer) {
234 1 int readdata;
235 1 char i=0xFF;
236 1 do{
237 2 // put LSB in the int
238 2 readdata = *a_buffer;
239 2 // increment buffer pointer
240 2 a_buffer++;
241 2 // put MSB in the int
C51 COMPILER V7.00 IDE_LIB 01/05/2004 23:20:12 PAGE 5
242 2 readdata = (*a_buffer << 8) | readdata;
243 2 // increment buffer pointer
244 2 a_buffer++;
245 2 // write byte to IDE
246 2 ide_wr(ide_data,readdata);
247 2 // next word
248 2 i--;
249 2 } while(i != 0);
250 1 }
251
252 /*
253 ------------ low level IDE routines ---------------
254 */
255
256 /*
257 Read register from IDE and return it
258 */
259 int ide_rd(char a_reg) {
260 1 int output = 0;
261 1 // config 8255 in read mode
262 1 cfg_8255 = rd_ide_8255;
263 1 // put adress on the control lines
264 1 ide_8255_ctl = a_reg;
265 1 // pulse read line
266 1 ide_8255_ctl = a_reg | ide_rd_line;
267 1 // put MSB in upper part of int
268 1 output = ide_8255_msb;
269 1 output = output << 8;
270 1 // put LSB in lower part of int
271 1 output = output | ide_8255_lsb;
272 1 // de assert all control pins
273 1 ide_8255_ctl = 0;
274 1 // return output
275 1 return output;
276 1 }
277
278 /*
279 Write to a_reg and write a_input to the IDE register
280 */
281 void ide_wr(char a_reg, int a_input){
282 1 // config 8255 in write mode
283 1 cfg_8255 = wr_ide_8255;
284 1 // write LSB to IDE
285 1 ide_8255_lsb = a_input & 0x00FF;
286 1 // write MSB to IDE
287 1 ide_8255_msb = a_input >> 8;
288 1 // put reg address in control reg
289 1 ide_8255_ctl = a_reg;
290 1 // assert write pin
291 1 ide_8255_ctl = a_reg | ide_wr_line;
292 1 // de assert all control pins
293 1 ide_8255_ctl = 0;
294 1 // put 8255 in read mode
295 1 cfg_8255 = rd_ide_8255;
296 1 }
297
298 // resets the IDE by flipping the reset line
299 void ide_hard_reset (void) {
300 1 int i;
301 1 // put 8255 in write mode
302 1 cfg_8255 = wr_ide_8255;
303 1 // toggle reset line
C51 COMPILER V7.00 IDE_LIB 01/05/2004 23:20:12 PAGE 6
304 1 ide_8255_ctl = ide_rst_line;
305 1 // wait
306 1 for(i=0;i<255;i++);
307 1 // reset all lines
308 1 ide_8255_ctl = 0;
309 1 }
310
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 1016 ----
CONSTANT SIZE = 71 ----
XDATA SIZE = ---- 48
PDATA SIZE = ---- ----
DATA SIZE = ---- ----
IDATA SIZE = ---- ----
BIT SIZE = ---- ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -