⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ide_base.c

📁 一个简单的能够直接操作IDE接口的函数库
💻 C
字号:
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//					    ATA Disc Raw IO Library for AVR 
//								  V0.1a
// 	  							Rob Riglar
//							Copyright 2003,2004 
//
//   					  Email: rob@robriglar.com
//
//			    Compiled with Imagecraft C Compiler for the AVR series
//-----------------------------------------------------------------------------
//
// This file is part of ATA Disc Raw IO Library.
//
// ATA Disc Raw IO Library is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// ATA Disc Raw IO Library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ATA Disc Raw IO Library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Set_Address: Set the Address on A1 A0 A2 pins
//
// Parameters: Byte Address
//
// Returns: None
//
// Functions Used: None
//
//-----------------------------------------------------------------------------
void Set_Address(byte Address)
{
byte tempdata=0;

	 if (Address&0x80) tempdata = tempdata + IDESIG_RST;
	 if (Address&0x40) tempdata = tempdata + IDESIG_WR;
	 if (Address&0x20) tempdata = tempdata + IDESIG_RD;
	 if (Address&0x10) tempdata = tempdata + IDESIG_A0;
	 if (Address&0x08) tempdata = tempdata + IDESIG_A1;
	 if (Address&0x04) tempdata = tempdata + IDESIG_A2;
	 if (Address&0x02) tempdata = tempdata + IDESIG_CS0;
	 if (Address&0x01) tempdata = tempdata + IDESIG_CS1;

	 SetAddressOutput;
	 ADDRESS_PORT = tempdata;			   // Send out value passed in
}
//-----------------------------------------------------------------------------
// Wait_Ready: Pauses execution until Ready = 1 in the status register
// A timeout delay should be added to improve this function
//
// Parameters: None
//
// Returns: None
//
// Functions Used: ReadReg
//
//-----------------------------------------------------------------------------
void Wait_Ready(void)
{
   byte statbyte;
   byte flag = 0;
   while (!flag)
	  {
 	  statbyte = ReadReg(STATUS); 	     // Read Status Register
	  if (statbyte & 0x40) flag = 1;     // Ready bit is in pos 6
	  }
}
//-----------------------------------------------------------------------------
// ReadReg: Function for reading from a specified register of the ATA device
//
// Parameters: Byte Address of Register to be read
//
// Returns: Byte data read from register
//
// Functions Used: Set_Address
//
//-----------------------------------------------------------------------------
byte ReadReg(byte reg)
{
    byte tempinput;
    DATALOW_OUTPORT=PULLUPSON;       // Activate pullups
    DATALOW_DIR=ALLINPUT;            // Make input

	Set_Address(reg);				 // Send out address
    SET_IDE_WR;						 // Make sure WR is high
    CLR_IDE_RD;						 // Activate (low) RD
    NOP();							 // Wait
    NOP();
    NOP();
    tempinput=DATALOW_INPORT;		 // Read D0-D7
    NOP();							 // Wait
    SET_IDE_RD;						 // Deassert RD
    NOP();
    return(tempinput);				 // Return register value
}

//-----------------------------------------------------------------------------
// Wait_ReadyBusy: Halts further execution until Ready = 1 and Busy = 0 in 
// status register
//
// Parameters: None
//
// Returns: None
//
// Functions Used: ReadReg
//
//-----------------------------------------------------------------------------
void Wait_ReadyBusy(void)
{
byte statbyte;
byte flag = 0;
while (!flag)
	  {
 	  statbyte = ReadReg(STATUS);	// Read Status register
	  // If RDY = 1 and BUSY = 0 leave loop  
	  if ((statbyte & 0x40) && ((statbyte & 0x80)==0)) flag = 1;
	  }
}
//-----------------------------------------------------------------------------
// Wait_DRQ: Halts execution until DRQ is asserted
//
// Parameters: None
//
// Returns: None
//
// Functions Used: ReadReg
//
//-----------------------------------------------------------------------------
void Wait_DRQ(void)
{
byte statbyte;
byte flag = 0;
while (!flag)
	   {
 	    statbyte = ReadReg(STATUS);		 // DRQ is in status register
	    if (statbyte & 0x08) flag = 1;
	   }
}
//-----------------------------------------------------------------------------
// WriteReg: Write a byte of data to a register specified
//
// Parameters: Byte Address of register and Byte data to be written
//
// Returns: None
//
// Functions Used: Wait_ReadyBusy, Set_Address
//
//-----------------------------------------------------------------------------
void WriteReg(byte Address, byte Data)
{
	Wait_ReadyBusy();  				  // Wait for Drive to be Ready
 	DATALOW_DIR=ALLOUTPUT;   		  // Make Data lines outputs
    DATAHIGH_DIR=ALLOUTPUT;
	Set_Address(Address);  			  // Set Address
	SET_IDE_RD;			   			  // RD must be high (inactive)
    CLR_IDE_WR;			   			  // Assert WR (active low)
delay_us(1);
	DATALOW_OUTPORT = Data;	  		  // Output Data onto Data bus
	DATAHIGH_OUTPORT = 0x00;		  // As byte writing ignore MSByte
delay_us(1);
    SET_IDE_WR;		   				  // Deassert WR
}
//-----------------------------------------------------------------------------
// ReadWord: Reads a word (16 bits) of data from a specified register
//
// Parameters: Byte Address of register to be read
//
// Returns: Word of data read
//
// Functions Used: Wait_ReadyBusy, Set_Address
//
//-----------------------------------------------------------------------------
word ReadWord(byte reg)
{	 
    
	byte templ, temph;
	Wait_ReadyBusy();  				  // Wait for Drive to be Ready
    DATALOW_OUTPORT=PULLUPSON;        // Activate pullups
    DATALOW_DIR=ALLINPUT;             // Make input
    DATAHIGH_OUTPORT=PULLUPSON;       // Activate pullups
    DATAHIGH_DIR=ALLINPUT;            // Make input

	Set_Address(reg);				 // Send out address
    SET_IDE_WR;						 // Make sure WR is high
    CLR_IDE_RD;						 // Activate (low) RD

    templ = DATALOW_INPORT;		 	 // Read D0-D7
    temph = DATAHIGH_INPORT;		 // Read D8-D15
delay_us(1);						 // Wait
    SET_IDE_RD;						 // Deassert RD
delay_us(1);
    return (templ + (temph << 8));	 // Return register value
}
//-----------------------------------------------------------------------------
// WriteWord: Write a word to a register address
//
// Parameters: Byte of Address, Word of data
//
// Returns: None
//
// Functions Used: Wait_ReadyBusy, Set_Address
//
//-----------------------------------------------------------------------------
void WriteWord(byte Address, word Data)
{
	Wait_ReadyBusy();  				  // Wait for Drive to be Ready
    DATALOW_DIR=ALLOUTPUT;   		  // Make outputs
    DATAHIGH_DIR=ALLOUTPUT;
	Set_Address(Address);  			  // Set Address
	SET_IDE_RD;			   			  // RD must be high (inactive)
    CLR_IDE_WR;			   			  // Assert WR (active low)
delay_us(2);
	DATALOW_OUTPORT = (Data&0x00FF);  // Output Data
	DATAHIGH_OUTPORT = (Data&0xFF00);
delay_us(2);
    SET_IDE_WR;		   				  // Deassert WR
}

//-----------------------------------------------------------------------------
// CheckforError: Reads status register, and if an error is preset then returns 0
// if no error has occurred then a 0 is returned
//
// Parameters: None
//
// Returns: Byte
//
// Functions Used: ReadReg
//
//-----------------------------------------------------------------------------
byte CheckforError(void)
{
 	  byte statbyte;
	  statbyte = ReadReg(STATUS);	// Read Status Register
  	  if (statbyte & 0x01) return 1; // Is LSB (error bit) is set then return 1
	  else return 0;
}
//-----------------------------------------------------------------------------
// ReadErrors: If an error was detected, this function can be called to see which
// error flags were set.
// (TO DO: Put meaningfull Words In)
//
// Parameters: None
//
// Returns: None
//
// Functions Used: ReadReg, printf
//
//-----------------------------------------------------------------------------
void ReadErrors(void)
{
 	 byte errors;
	 errors = ReadReg(ERROR); // Read Error Register

	 printf("\r\nError Report");
	 if (errors &0x80) printf("\r\nBit 7 Set");
	 else      		   printf("\r\nBit 7 Clr");

	 if (errors &0x40) printf("\r\nBit 6 Set");
   	 else    		   printf("\r\nBit 6 Clr");

	 if (errors &0x20) printf("\r\nBit 5 Set");
	 else    		   printf("\r\nBit 5 Clr");

	 if (errors &0x10) printf("\r\nBit 4 Set");
   	 else    		   printf("\r\nBit 4 Clr");
   
   	 if (errors &0x08) printf("\r\nBit 3 Set");
   	 else    		   printf("\r\nBit 3 Clr");

	 if (errors &0x04) printf("\r\nBit 2 Set : Bad Parameters for Rd/Wr");
   	 else    		   printf("\r\nBit 2 Clr");

	 if (errors &0x02) printf("\r\nBit 1 Set");
   	 else    		   printf("\r\nBit 1 Clr");

	 if (errors &0x01) printf("\r\nBit 0 Set");
   	 else    		   printf("\r\nBit 0 Clr");
	 while (1);
}
//-----------------------------------------------------------------------------
// DataInputSetup: Makes Data line D0 - D7, D8 - D15 as inputs with internal
// pullups enabled.
//
// Parameters: None
//
// Returns: None
//
// Functions Used: None
//
//-----------------------------------------------------------------------------
void DataInputSetup(void)
{
	DATALOW_OUTPORT = PULLUPSON;		// Switch internal Port pullups on 
	DATAHIGH_OUTPORT= PULLUPSON;
    DATALOW_DIR=ALLINPUT;       		// Switch data lines to input
    DATAHIGH_DIR=ALLINPUT;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -