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

📄 ide_base.c

📁 嵌入式系统中的完整FAT16和FAT32源码
💻 C
字号:
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//					    FAT32 File IO Library for AVR 
//								  V0.1c
// 	  							Rob Riglar
//							Copyright 2003,2004 
//
//   					  Email: rob@robriglar.com
//
//			    Compiled with Imagecraft C Compiler for the AVR series
//-----------------------------------------------------------------------------
//
// This file is part of FAT32 File IO Library.
//
// FAT32 File 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.
//
// FAT32 File 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 FAT32 File 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 tempinputL;
	word tempinputH;
    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
    NOP();							 // Wait
    NOP();
    NOP();
    tempinputL=DATALOW_INPORT;		 // Read D0-D7
    tempinputH=DATAHIGH_INPORT;		 // Read D8-D15
    NOP();							 // Wait
    SET_IDE_RD;						 // Deassert RD
    NOP();
    return (tempinputL + (tempinputH << 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\nReserved bit....");
	 

	 if (errors &0x40) printf("\r\nUNC bit: Uncorrectable data error");
   	 

	 if (errors &0x20) printf("\r\nMC bit: The media has changed");
	 

	 if (errors &0x10) printf("\r\nIDNF bit: Sector ID not found");
   	 
   
   	 if (errors &0x08) printf("\r\nMCR bit: Media Change Requested");
   	 

	 if (errors &0x04) printf("\r\nABRT bit: Bad Parameters for Rd/Wr; possible out of range IO");
   	 

	 if (errors &0x02) printf("\r\nTK0NF bit: Can't find track 0; possible disc failure");
   	 

	 if (errors &0x01) printf("\r\AMNF bit: Address mark not found");
   	 
	 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;
}

//-----------------------------------------------------------------------------
// Fetch_ID_Max_LBA: Reads drive parameters and returns Max LBA address
//
// Parameters: If silent set then no terminal output, else prints results
//
// Returns: Max LBA address (32bits)
//
//-----------------------------------------------------------------------------
UI32 Fetch_ID_Max_LBA(byte silent)
{
 	 	byte i,cnt;
		byte chardata;
		word tempbuffer[65];
		UI32 TotalLBAs=0;

   		// Wait till not busy and RDY?
		Wait_ReadyBusy();

   		// Send Command for drive identification 
   		WriteReg(COMMAND, DRIVEID);

   		// Wait for DRQ
		Wait_DRQ();

   		// Read in first 62 bytes of the drive identification
   	    for (i=0; i<62; i++)
	   	   	{
		   	// Read data words from drives buffer
		   	tempbuffer[i] = ReadWord(DATA);		   
		   	}

		// Assuming drive supports LBA find max LBA sector
		TotalLBAs = tempbuffer[61];
		TotalLBAs = TotalLBAs << 16;
		TotalLBAs = TotalLBAs + tempbuffer[60];	
			
		if (!silent)
		{
		printf("\r\nHard Disc Auto Detect Parameters");
		printf("\r\n--------------------------------\r\n");
		
		// Detect HDD or CDROM
		printf("\r\nType of device: ");		
		if (tempbuffer[0]&0x8000) printf("ATA Device ");
		else printf("ATAPI Device ");
		
		// Detect removable media
		if (tempbuffer[i]&0x0080) printf("which has removable media");

		// Heads 
		printf("\r\nThe number of heads is = %d",tempbuffer[3]);
		
		// Cylinders
		printf("\r\nThe number of Cylinders is =  %d",tempbuffer[1]);

		// Sectors Per Track 
		printf("\r\nThe number of Sectors per track is = %d", tempbuffer[6]);

		// Serial Number
		printf("\r\nThe number of Serial Number of the device is = ");
		for (cnt=10; cnt<19; cnt++) 
		{
				chardata = tempbuffer[cnt]>>8;
				putchar(chardata);
				
				chardata = tempbuffer[cnt];
				putchar(chardata);
		}
		
		// Model Number
		printf("\r\nThe number of Model Number of the device is = ");		
		for (cnt=27; cnt<46; cnt++) 
		{
		 		chardata = tempbuffer[cnt]>>8;
				putchar(chardata);
				
				chardata = tempbuffer[cnt];
				putchar(chardata);
		}
		
		// CHS or LBA
		if(!((tempbuffer[49] >> 8) & 0x1)) 
			  printf("\r\nCHS Mode Only (NO LBA)");
		else
			  printf("\r\nLBA Supported");
		
		// Report max lba address
		printf("\r\nLBA sectors is 0x%lx", TotalLBAs);
		}  

		// Return Max LBA sector address in global drive information		
		return TotalLBAs;  
}

⌨️ 快捷键说明

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