Main Page   Data Structures   File List   Data Fields   Globals  

ata_if.c

Go to the documentation of this file.
00001 /*! \file ata_if.c \brief IDE-ATA hard disk interface driver. */
00002 //*****************************************************************************
00003 //
00004 // File Name    : 'ata_if.c'
00005 // Title        : IDE-ATA interface driver for hard disks
00006 // Author       : Pascal Stang
00007 // Date         : 11/22/2000
00008 // Revised      : 12/29/2000
00009 // Version      : 0.3
00010 // Target MCU   : ATmega103 (should work for Atmel AVR Series)
00011 // Editor Tabs  : 4
00012 //
00013 // NOTE: This code is currently below version 1.0, and therefore is considered
00014 // to be lacking in some functionality or documentation, or may not be fully
00015 // tested.  Nonetheless, you can expect most functions to work.
00016 //
00017 // This code is distributed under the GNU Public License
00018 //      which can be found at http://www.gnu.org/licenses/gpl.txt
00019 //
00020 //*****************************************************************************
00021 
00022 #ifndef WIN32
00023     #include <avr/io.h>
00024     #include <avr/interrupt.h>
00025     #include <avr/signal.h>
00026     #include <avr/progmem.h>
00027 //  #include <stdio.h>
00028 #endif
00029 #include "global.h"
00030 #include "systimer.h"
00031 #include "uart.h"
00032 
00033 #include "ata_if.h"
00034 
00035 //#define DEBUG_ATA 1
00036 
00037 // global variables
00038 
00039 // drive information
00040 typeDriveInfo ataDriveInfo;
00041 
00042 
00043 void ataInit(void)
00044 {
00045 
00046 }
00047 
00048 void ataDriveInit(void)
00049 {
00050     u08 i;
00051     unsigned char* buffer = (unsigned char*) SECTOR_BUFFER_ADDR;
00052 
00053     // read drive identity
00054     uartPrintfProgStrM("\r\nScanning IDE interface...\r\n");
00055     // Wait for drive to be ready
00056     ataStatusWait(ATA_SR_BSY, ATA_SR_BSY);
00057     // issue identify command
00058     ataWriteByte(ATA_REG_CMDSTATUS1, 0xEC);
00059     // wait for drive to request data transfer
00060     ataStatusWait(ATA_SR_DRQ, ATA_SR_DRQ);
00061     timerPause(200);
00062     // read in the data
00063     ataReadDataBuffer(buffer, 512);
00064 
00065     // set local drive info parameters
00066     ataDriveInfo.cylinders =        *( ((unsigned int*) buffer) + ATA_IDENT_CYLINDERS );
00067     ataDriveInfo.heads =                *( ((unsigned int*) buffer) + ATA_IDENT_HEADS );
00068     ataDriveInfo.sectors =          *( ((unsigned int*) buffer) + ATA_IDENT_SECTORS );
00069     ataDriveInfo.LBAsupport =       *( ((unsigned int*) buffer) + ATA_IDENT_FIELDVALID );
00070     ataDriveInfo.sizeinsectors =    *( (unsigned long*) (buffer + ATA_IDENT_LBASECTORS*2) );
00071     // copy model string
00072     for(i=0; i<40; i+=2)
00073     {
00074         // correct for byte order
00075         ataDriveInfo.model[i  ] = buffer[(ATA_IDENT_MODEL*2) + i + 1];
00076         ataDriveInfo.model[i+1] = buffer[(ATA_IDENT_MODEL*2) + i    ];
00077     }
00078     // terminate string
00079     ataDriveInfo.model[40] = 0;
00080 
00081     // process and print info
00082     if(ataDriveInfo.LBAsupport)
00083     {
00084         // LBA support
00085         uartPrintf("Drive 0: %dMB ", ataDriveInfo.sizeinsectors/(1000000/512) );
00086         uartPrintf("LBA mode -- MODEL: ");
00087     }
00088     else
00089     {
00090         // CHS, no LBA support
00091         // calculate drive size
00092         ataDriveInfo.sizeinsectors = (unsigned long) ataDriveInfo.cylinders*
00093                                                 ataDriveInfo.heads*ataDriveInfo.sectors;
00094         uartPrintf("Drive 0: %dMB ", ataDriveInfo.sizeinsectors/(1000000/512) );
00095         uartPrintf("CHS mode C=%d H=%d S=%d -- MODEL: ", ataDriveInfo.cylinders, ataDriveInfo.heads, ataDriveInfo.sectors );
00096     }
00097     // print model information  
00098     uartPrintfStr(ataDriveInfo.model); uartPrintfCRLF();
00099 
00100     // initialize local disk parameters
00101     //ataDriveInfo.cylinders = ATA_DISKPARM_CLYS;
00102     //ataDriveInfo.heads = ATA_DISKPARM_HEADS;
00103     //ataDriveInfo.sectors = ATA_DISKPARM_SECTORS;
00104 
00105 }
00106 
00107 void ataDiskErr(void)
00108 {
00109     unsigned char b;
00110 
00111     b = ataReadByte(ATA_REG_ERROR); 
00112     uartPrintfProgStrM("ATA Error: "); 
00113     uartPrintfu08(b); 
00114     uartPrintfCRLF();
00115 }
00116 
00117 
00118 void ataPrintSector( u08 *Buffer)
00119 {
00120     u08 i;
00121     u16 j;
00122     u08 *buf;
00123     u08 s;
00124 
00125     buf = Buffer;
00126     
00127     // print the low order address indicies
00128     uartPrintfProgStrM("     00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F  0123456789ABCDEF\r\n");
00129     uartPrintfProgStrM("     -----------------------------------------------  ---- ASCII -----\r\n");
00130     
00131     // print the data
00132     for(j=0; j<0x20; j++)
00133     {
00134         // print the high order address index for this line
00135         uartPrintfu16(j<<4);
00136         uartPrintfProgStrM(" ");
00137 
00138         // print the hex data
00139         for(i=0; i<0x10; i++)
00140         {
00141             uartPrintfu08(buf[(j<<4)+i]);
00142             uartPrintfProgStrM(" ");
00143         }
00144         
00145         // leave some space
00146         uartPrintfProgStrM(" ");
00147 
00148         // print the ascii data
00149         for(i=0; i<0x10; i++)
00150         {
00151             s = buf[(j<<4)+i]; 
00152             // make sure character is printable
00153             if(s >= 0x20)
00154             {
00155                 uartPrintChar(s);
00156             }
00157             else
00158             {
00159                 uartPrintChar(0x20);
00160             }
00161 
00162         }
00163         uartPrintfCRLF();
00164     }
00165 }
00166 
00167 void ataReadDataBuffer(u08 *Buffer, u16 numBytes)
00168 {
00169     unsigned int i;
00170 
00171     //sbi(MCUCR, SRW);          // enable RAM waitstate
00172 
00173     // read data from drive
00174     for (i=0; i<(numBytes/16); i++)
00175     {
00176         // optimize by reading 16 bytes in-line before looping
00177         *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL);
00178         *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH);
00179         *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL);
00180         *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH);
00181         *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL);
00182         *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH);
00183         *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL);
00184         *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH);
00185         *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL);
00186         *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH);
00187         *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL);
00188         *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH);
00189         *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL);
00190         *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH);
00191         *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL);
00192         *Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH);
00193     }
00194     //cbi(MCUCR, SRW);          // disable RAM waitstate
00195     
00196 }
00197 
00198 void ataWriteDataBuffer(u08 *Buffer, u16 numBytes)
00199 {
00200     register unsigned char temp;
00201     unsigned int i;
00202 
00203     //sbi(MCUCR, SRW);          // enable RAM waitstate
00204 
00205     // write data to drive
00206     for (i=0; i<(numBytes/16); i++)     
00207     {
00208         // optimize by writing 16 bytes in-line before looping
00209         // keep byte order correct by using temp register
00210         temp = *Buffer++;
00211         *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++;
00212         *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp;
00213         temp = *Buffer++;
00214         *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++;
00215         *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp;
00216         temp = *Buffer++;
00217         *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++;
00218         *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp;
00219         temp = *Buffer++;
00220         *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++;
00221         *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp;
00222         temp = *Buffer++;
00223         *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++;
00224         *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp;
00225         temp = *Buffer++;
00226         *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++;
00227         *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp;
00228         temp = *Buffer++;
00229         *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++;
00230         *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp;
00231         temp = *Buffer++;
00232         *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++;
00233         *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp;
00234     }
00235     //cbi(MCUCR, SRW);          // disable RAM waitstate
00236 
00237 }
00238 
00239 u08 ataStatusWait(u08 mask, u08 waitStatus)
00240 {
00241     register u08 status;
00242 
00243     delay(100);
00244 
00245     // wait for desired status
00246     while( ((status = ataReadByte(ATA_REG_CMDSTATUS1)) & mask) == waitStatus );
00247 
00248     return status;
00249 }
00250 
00251 
00252 unsigned char ataReadSectorsCHS(    unsigned char Drive, 
00253                                             unsigned char Head, 
00254                                             unsigned int Track,
00255                                             unsigned char Sector,
00256                                             unsigned int numsectors,
00257                                             unsigned char *Buffer)
00258 {
00259     unsigned char temp;
00260 
00261     // Wait for drive to be ready
00262     temp = ataStatusWait(ATA_SR_BSY, ATA_SR_BSY);
00263 
00264     // Prepare parameters...
00265     ataWriteByte(ATA_REG_HDDEVSEL, 0xA0+(Drive ? 0x10:00)+Head); // CHS mode/Drive/Head
00266     ataWriteByte(ATA_REG_CYLHI, Track>>8);          // MSB of track
00267     ataWriteByte(ATA_REG_CYLLO, Track);             // LSB of track
00268     ataWriteByte(ATA_REG_STARTSEC, Sector);     // sector
00269     ataWriteByte(ATA_REG_SECCOUNT, numsectors); // # of sectors
00270 
00271     // Issue read sector command...
00272     ataWriteByte(ATA_REG_CMDSTATUS1, 0x21);
00273 
00274     // Wait for drive to be ready
00275     temp = ataStatusWait(ATA_SR_BSY, ATA_SR_BSY);
00276 
00277     if (temp & ATA_SR_ERR)
00278     {
00279         uartPrintfProgStrM("RD ERR\r\n");
00280         return 1;
00281     }
00282 
00283     // Wait for drive to request data transfer
00284     ataStatusWait(ATA_SR_DRQ, 0);
00285 
00286     // read data from drive
00287     ataReadDataBuffer(Buffer, 512*numsectors);
00288 
00289     // Return the error bit from the status register...
00290     temp = ataReadByte(ATA_REG_CMDSTATUS1); // read status register
00291 
00292     return (temp & ATA_SR_ERR) ? 1:0;
00293 }
00294 
00295 
00296 unsigned char ataWriteSectorsCHS(unsigned char Drive, 
00297                                             unsigned char Head, 
00298                                             unsigned int Track,
00299                                             unsigned char Sector,
00300                                             unsigned int numsectors,
00301                                             unsigned char *Buffer)
00302 {
00303     unsigned char temp;
00304 
00305     // Wait for drive to be ready
00306     temp = ataStatusWait(ATA_SR_BSY, ATA_SR_BSY);
00307 
00308     // Prepare parameters...
00309     ataWriteByte(ATA_REG_HDDEVSEL, 0xA0+(Drive ? 0x10:00)+Head); // CHS mode/Drive/Head
00310     ataWriteByte(ATA_REG_CYLHI, Track>>8);          // MSB of track
00311     ataWriteByte(ATA_REG_CYLLO, Track);             // LSB of track
00312     ataWriteByte(ATA_REG_STARTSEC, Sector);     // sector
00313     ataWriteByte(ATA_REG_SECCOUNT, numsectors); // # of sectors
00314 
00315     // Issue write sector command
00316     ataWriteByte(ATA_REG_CMDSTATUS1, 0x31);
00317 
00318     //delay(100);
00319 
00320     // Wait for drive to request data transfer
00321     ataStatusWait(ATA_SR_DRQ, 0);
00322 
00323     // write data to drive
00324     ataWriteDataBuffer(Buffer, 512*numsectors);
00325     
00326     // Wait for drive to finish write
00327     temp = ataStatusWait(ATA_SR_BSY, ATA_SR_BSY);
00328 
00329     // check for errors
00330     if (temp & ATA_SR_ERR)
00331     {
00332         uartPrintfProgStrM("WR ERR\r\n");
00333         return 1;
00334     }
00335 
00336     // Return the error bit from the status register...
00337     return (temp & ATA_SR_ERR) ? 1:0;
00338 }
00339 
00340 unsigned char ataReadSectorsLBA(    unsigned char Drive, 
00341                                             unsigned long lba,
00342                                             unsigned int numsectors,
00343                                     unsigned char *Buffer)
00344 {
00345     unsigned int cyl, head, sect;
00346     unsigned char temp;
00347 
00348 #ifdef DEBUG_ATA
00349     uartPrintfProgStrM("ATA LBA read ");
00350     uartPrintfu32(lba); uartPrintfProgStrM(" ");
00351     uartPrintfu16(numsectors); uartPrintfProgStrM(" ");
00352     uartPrintfu16((unsigned int)Buffer); 
00353     uartPrintfCRLF();
00354 #endif
00355 
00356     sect = (int) ( lba & 0x000000ffL );
00357     lba = lba >> 8;
00358     cyl = (int) ( lba & 0x0000ffff );
00359     lba = lba >> 16;
00360     head = ( (int) ( lba & 0x0fL ) ) | ATA_HEAD_USE_LBA;
00361 
00362     temp = ataReadSectorsCHS( Drive, head, cyl, sect, numsectors, Buffer );
00363 
00364     if(temp)
00365         ataDiskErr();
00366     return temp;
00367 }
00368 
00369 unsigned char ataWriteSectorsLBA(   unsigned char Drive, 
00370                                                 unsigned long lba,
00371                                                 unsigned int numsectors,
00372                                         unsigned char *Buffer)
00373 {
00374     unsigned int cyl, head, sect;
00375     unsigned char temp;
00376 
00377 #ifdef DEBUG_ATA
00378     uartPrintfProgStrM("ATA LBA write ");
00379     uartPrintfu32(lba); uartPrintfProgStrM(" ");
00380     uartPrintfu16(numsectors); uartPrintfProgStrM(" ");
00381     uartPrintfu16((unsigned int)Buffer); 
00382     uartPrintfCRLF();
00383 #endif
00384 
00385     sect = (int) ( lba & 0x000000ffL );
00386     lba = lba >> 8;
00387     cyl = (int) ( lba & 0x0000ffff );
00388     lba = lba >> 16;
00389     head = ( (int) ( lba & 0x0fL ) ) | ATA_HEAD_USE_LBA;
00390 
00391     temp = ataWriteSectorsCHS( Drive, head, cyl, sect, numsectors, Buffer );
00392 
00393     if(temp)
00394         ataDiskErr();
00395     return temp;
00396 }                                   
00397 
00398 
00399 unsigned char ataReadSectors(   unsigned char Drive, 
00400                                         unsigned long lba,
00401                                         unsigned int numsectors,
00402                                 unsigned char *Buffer)
00403 {
00404     unsigned int cyl, head, sect;
00405     unsigned char temp;
00406 
00407     // check if drive supports native LBA mode
00408     if(ataDriveInfo.LBAsupport)
00409     {
00410         // drive supports using native LBA
00411         temp = ataReadSectorsLBA(Drive, lba, numsectors, Buffer);
00412     }
00413     else
00414     {
00415         // drive required CHS access
00416         #ifdef DEBUG_ATA
00417             // do this defore destroying lba
00418             uartPrintfProgStrM("ATA LBA for CHS read: ");
00419             uartPrintfProgStrM("LBA="); uartPrintfu32(lba); uartPrintfProgStrM(" ");
00420         #endif
00421 
00422         // convert LBA to pseudo CHS
00423         // remember to offset the sector count by one
00424         sect = (u08) (lba % ataDriveInfo.sectors)+1;
00425         lba = lba / ataDriveInfo.sectors;
00426         head = (u08) (lba % ataDriveInfo.heads);
00427         lba = lba / ataDriveInfo.heads;
00428         cyl = (u16) lba;
00429 
00430         #ifdef DEBUG_ATA
00431             uartPrintfProgStrM("C:H:S=");
00432             uartPrintfu16(cyl); uartPrintfProgStrM(":");
00433             uartPrintfu08(head); uartPrintfProgStrM(":");
00434             uartPrintfu08(sect); uartPrintfCRLF();
00435         #endif
00436 
00437         temp = ataReadSectorsCHS( Drive, head, cyl, sect, numsectors, Buffer );
00438     }
00439 
00440     if(temp)
00441         ataDiskErr();
00442     return temp;
00443 }
00444 
00445 
00446 unsigned char ataWriteSectors(unsigned char Drive, 
00447                                         unsigned long lba,
00448                                         unsigned int numsectors,
00449                                 unsigned char *Buffer)
00450 {
00451     unsigned int cyl, head, sect;
00452     unsigned char temp;
00453 
00454     // check if drive supports native LBA mode
00455     if(ataDriveInfo.LBAsupport)
00456     {
00457         // drive supports using native LBA
00458         temp = ataWriteSectorsLBA(Drive, lba, numsectors, Buffer);
00459     }
00460     else
00461     {
00462         // drive required CHS access
00463         #ifdef DEBUG_ATA
00464             // do this defore destroying lba
00465             uartPrintfProgStrM("ATA LBA for CHS write: ");
00466             uartPrintfProgStrM("LBA="); uartPrintfu32(lba); uartPrintfProgStrM(" ");
00467         #endif
00468 
00469         // convert LBA to pseudo CHS
00470         // remember to offset the sector count by one
00471         sect = (u08) (lba % ataDriveInfo.sectors)+1;
00472         lba = lba / ataDriveInfo.sectors;
00473         head = (u08) (lba % ataDriveInfo.heads);
00474         lba = lba / ataDriveInfo.heads;
00475         cyl = (u16) lba;
00476 
00477         #ifdef DEBUG_ATA
00478             uartPrintfProgStrM("C:H:S=");
00479             uartPrintfu16(cyl); uartPrintfProgStrM(":");
00480             uartPrintfu08(head); uartPrintfProgStrM(":");
00481             uartPrintfu08(sect); uartPrintfCRLF();
00482         #endif
00483 
00484         temp = ataWriteSectorsCHS( Drive, head, cyl, sect, numsectors, Buffer );
00485     }
00486 
00487     if(temp)
00488         ataDiskErr();
00489     return temp;
00490 }                                   
00491 
00492 void ataDriveSelect(u08 DriveNo)
00493 {
00494     ataWriteByte(ATA_REG_HDDEVSEL, 0xA0+(DriveNo ? 0x10:00)); // Drive selection
00495 }
00496  
00497 //----------------------------------------------------------------------------
00498 // Set drive mode (STANDBY, IDLE)
00499 //----------------------------------------------------------------------------
00500 /*#define STANDBY 0
00501 #define IDLE    1
00502 #define SLEEP   2 
00503 */ 
00504 
00505 /*
00506 unsigned char SetMode(unsigned char DriveNo, unsigned char Mode, unsigned char PwrDown) 
00507 {
00508   WriteBYTE(CMD, 6, 0xA0 + (DriveNo ? 0x10:0x00)); // Select drive
00509   WriteBYTE(CMD, 2, (PwrDown ? 0x01:0x00)); // Enable automatic power down
00510   switch (Mode) 
00511   {
00512     case STANDBY: WriteBYTE(CMD,7, 0xE2); break;
00513     case IDLE:    WriteBYTE(CMD,7, 0xE3); break;
00514     // NOTE: To recover from sleep, either issue a soft or hardware reset !
00515     // (But not on all drives, f.ex seagate ST3655A it's not nessecary to reset
00516     // but only to go in Idle mode, But on a Conner CFA170A it's nessecary with
00517     // a reset)
00518     case SLEEP:   WriteBYTE(CMD,7, 0xE6); break;
00519   }
00520   Timer10mSec=10000;
00521   while ((ReadBYTE(CMD,7) & 0xC0)!=0x40 && Timer10mSec); // Wait for DRDY & NOT BUSY 
00522   if (Timer10mSec==0) return 0xFF;                       //   or timeout
00523  
00524   // Return the error register...
00525   return ReadBYTE(CMD, 1);
00526 }
00527 
00528 */
00529 
00530 u08 ataReadByte(u08 reg)
00531 {
00532     register u08 ret;
00533     //sbi(MCUCR, SRW);          // enable RAM waitstate
00534     ret = *((volatile unsigned char*) ATA_REG_BASE + reg);
00535     //cbi(MCUCR, SRW);          // disable RAM waitstate
00536     return ret;
00537 }
00538 
00539 void ataWriteByte(u08 reg, u08 data)
00540 {
00541     //sbi(MCUCR, SRW);          // enable RAM waitstate
00542     *((volatile unsigned char*) ATA_REG_BASE + reg) = data;
00543     //cbi(MCUCR, SRW);          // disable RAM waitstate
00544 }
00545 
00546  
00547 void ataShowRegisters(unsigned char DriveNo) 
00548 { 
00549     ataWriteByte(ATA_REG_HDDEVSEL, 0xA0 + (DriveNo ? 0x10:0x00)); // Select drive
00550     
00551     uartPrintfProgStrM("Reg 0=");   uartPrintfu08(ataReadByte(ATA_REG_DATAL )); uartPrintfProgStrM(" ");
00552     uartPrintfProgStrM("1=");       uartPrintfu08(ataReadByte(ATA_REG_ERROR )); uartPrintfProgStrM(" ");
00553     uartPrintfProgStrM("2=");       uartPrintfu08(ataReadByte(ATA_REG_SECCOUNT));   uartPrintfProgStrM(" ");
00554     uartPrintfProgStrM("3=");       uartPrintfu08(ataReadByte(ATA_REG_STARTSEC));   uartPrintfProgStrM(" ");
00555     uartPrintfProgStrM("4=");       uartPrintfu08(ataReadByte(ATA_REG_CYLLO )); uartPrintfProgStrM(" ");
00556     uartPrintfProgStrM("5=");       uartPrintfu08(ataReadByte(ATA_REG_CYLHI )); uartPrintfProgStrM(" ");
00557     uartPrintfProgStrM("6=");       uartPrintfu08(ataReadByte(ATA_REG_HDDEVSEL));   uartPrintfProgStrM(" ");
00558     uartPrintfProgStrM("7=");       uartPrintfu08(ataReadByte(ATA_REG_CMDSTATUS1)); uartPrintfProgStrM("\n\r");
00559 } 
00560 
00561 unsigned char ataSWReset(void)
00562 {
00563     ataWriteByte(ATA_REG_HDDEVSEL, 0x06);   // SRST and nIEN bits
00564     delay(10);  // 10uS delay
00565     ataWriteByte(ATA_REG_HDDEVSEL, 0x02);   // nIEN bits
00566     delay(10);  // 10 uS delay
00567    
00568    while( (ataReadByte(ATA_REG_CMDSTATUS1) & 0xC0) != 0x40 ); // Wait for DRDY and not BSY
00569     
00570     return ataReadByte(ATA_REG_CMDSTATUS1) + ataReadByte(ATA_REG_ERROR);
00571 }
00572 
00573 /*
00574 unsigned char ATA_Idle(unsigned char Drive)
00575 {
00576 
00577   WriteBYTE(CMD, 6, 0xA0 + (Drive ? 0x10:0x00)); // Select drive
00578   WriteBYTE(CMD,7, 0xE1);
00579 
00580   while ((ReadBYTE(CMD,7) & 0xC0)!=0x40); // Wait for DRDY & NOT BUSY 
00581 
00582   // Return the error register...
00583   return ReadBYTE(CMD, 1);
00584 }
00585 */

Generated on Tue Feb 4 20:18:36 2003 for Procyon AVRlib by doxygen1.3-rc2