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

📄 ide.c

📁 IDE接口实验 Embest Teach Kit II boot success Embest 44B0X Evaluation Board(EduKit II) IDE Test Exampl
💻 C
📖 第 1 页 / 共 3 页
字号:
	} while(status & BUSY);

	return ERR_NOERR;
}


/*
* name: WaitForDRDY()
* parameter: void
* return: bool
*			true, no busy any data is ready; flase, failed.
* description: waiting, till no busy and data is ready.
*/
static unsigned int WaitForDRDY(void)
{
	unsigned char status;

	do
	{
		status = ReadStatus();
		if(status & ERROR)
			return ReadError();

	} while((status & (BUSY|DRDY)) != DRDY);

	return ERR_NOERR;
}


/*
* name: WaitForDRQ()
* parameter: void
* return: status code.
* description: waiting, till no busy and occur data request.
*/
static unsigned int WaitForDRQ(void)
{
	unsigned char status;

	do
	{
		status = ReadStatus();
		if(status & ERROR)
			return ReadError();

	} while((status & (BUSY|DRQ)) != DRQ);

	return ERR_NOERR;
}


/*
* name: CheckStatus()
* parameter: void
* return: status code.
* description: executed command, check status.
*/
static unsigned int CheckStatus(void)
{
	unsigned char status;

	status = ReadStatus();
	if(status & (ERROR | DRQ))
	{
		if(status & ERROR)
			return ReadError();
	}

	if(!(status & DRDY))
		return ERR_AMNF;

	return ERR_NOERR;
}


/*
* name: WriteLBA()
* parameter: lba			---input, logical block address.
* return: void
* description: write lba registers.
*/
static void WriteLBA(unsigned long lba)
{
	WriteSectorNumber(lba & 0xff);
	WriteCylinder((lba >> 16) & 0xffff);
	WriteDriveHead((lba >> 8) & 0x1f);
}


/*
* name: IDE_Init()
* parameter: drive			---input, primary or slave drive.
* return: boolean
*			true --- found IDE drive, false --- otherwise
* description: initialize IDE drive.
*/
int IDE_Init(int drive)
{
	unsigned char err, cnt, num, dhd;
	unsigned short cyl;

	WriteDeviceControl(SRST|nIEN);
	delay(100);
	WriteDeviceControl(nIEN);

	if(drive & 0x1)
		WriteLBA(((drive & 0x1) << 12) | 1);

	err = ReadError();
	cnt = ReadSectorCount();
	num = ReadSectorNumber();
	cyl = ReadCylinder();
	dhd = ReadDriveHead();

	if(err == 1 && cnt == 1	&& num == 1	
		&& cyl == 0	 && (dhd == 0 || dhd == 0xb0))
	{
		return 1;
	}

	return 0;
}


/*
* name: IDE_Diagnostics()
* parameter: drive			---input, primary or slave drive.
*			 err			---output, drive error code.
* return: status code.
* description: diagnose IDE drive.
*/
unsigned int IDE_Diagnostics(int drive, enum DrvErr *err)
{
	unsigned int status;

	status = WaitForNoBUSY_igError();
	if(status != ERR_NOERR)
		return status;

	WriteDriveHead(((drive & 0x1) << 4));

	WriteCommand(EXECUTE_DRIVE_DIAGNOSTIC);
	status = WaitForNoBUSY_igError();
	if(status != ERR_NOERR)
		return status;

	*err = (enum DrvErr)ReadError();

	return status;
}


/*
* name: IDE_Diagnostics()
* parameter: drive			---input, primary or slave drive.
*			 id				---output, receive drive identification.
* return: status code.
* description: read drive identification.
*/
unsigned int IDE_Identification(int drive, struct DriveId *id)
{
	unsigned int i, status;
	unsigned short word;
	
	status = WaitForNoBUSY();
	if(status != ERR_NOERR)
		return status;

	WriteDriveHead(((drive & 0x1) << 4));

	WriteCommand(IDENTIFY_DRIVE);
	status = WaitForDRQ();
	if(status != ERR_NOERR)
		return status;

	memset(id, 0, sizeof(struct DriveId));

	                         ReadData();	/* 00h */
	id->cylinders          = ReadData();	/* 01h */
	                         ReadData();	/* 02h */
	id->heads              = ReadData();	/* 03h */
	id->bytes_per_track    = ReadData();	/* 04h */
	id->bytes_per_sector   = ReadData();	/* 05h */
	id->sectors_per_track  = ReadData();	/* 06h */
	                         ReadData();	/* 07h */
	                         ReadData();	/* 08h */
	id->vendor_id          = ReadData();	/* 09h */
	for(i=0; i<10; i++)						/* 0Ah - 13h */
	{
		word = ReadData();
		word = ((word & 0xff) << 8) | ((word & 0xff00) >> 8);
		*(unsigned short *)(id->serial_number + i*sizeof(short)) = word;
	}
	                          ReadData();	/* 14h */
	                          ReadData();	/* 15h */
	                          ReadData();	/* 16h */
	for(i=0; i<4; i++)						/* 17h - 1Ah */
	{
		word = ReadData();
		word = ((word & 0xff) << 8) | ((word & 0xff00) >> 8);
		*(unsigned short *)(id->firmware_version + i*sizeof(short)) = word;
	}
	for(i=0; i<20; i++)						/* 1Bh - 2Eh */
	{
		word = ReadData();
		word = ((word & 0xff) << 8) | ((word & 0xff00) >> 8);
		*(unsigned short *)(id->model_number + i*sizeof(short)) = word;
	}
	                         ReadData();	/* 2Fh */
	                         ReadData();	/* 30h */
	                         ReadData();	/* 31h */
	                         ReadData();	/* 32h */
	id->minimum_pio        = ReadData();	/* 33h */
	id->minimum_dma        = ReadData();	/* 34h */

	for(i=0x35; i<SECTOR_WORDS; i++)		/* 35h - 99h */
		ReadData();

	return CheckStatus();
}


/*
* name: IDE_ReadSectors()
* parameter: lba			---input, logical block address.
*			 buf			---output, receive sector data.
*			 count			---input, number of sector buffer.
* return: status code.
* description: read sectors data.
*/
unsigned int IDE_ReadSectors(unsigned long lba, 
		struct Sector *buf, unsigned char count)
{
	unsigned int i, status;
	unsigned short *ptr;

	status = WaitForNoBUSY();
	if(status != ERR_NOERR)
		return status;

	WriteSectorCount(count);
	WriteLBA(lba);

	WriteCommand(READ_SECTORS_WITH_RETRY);

	ptr = (unsigned short *)buf;
	do
	{
		status = WaitForDRQ();
		if(status != ERR_NOERR)
			return status;

		for(i=0; i<SECTOR_WORDS; i++)
			*ptr++ = ReadData();

	}while(--count);

	return CheckStatus();
}


/*
* name: IDE_WriteSectors()
* parameter: lba			---input, logical block address.
*			 buf			---input, sector data will be write.
*			 count			---input, number of sector buffer.
* return: status code.
* description: write sectors data.
*/
unsigned int IDE_WriteSectors(unsigned long lba,
		const struct Sector *buf, unsigned char count)
{
	unsigned int i, status;
	unsigned short *ptr;

	status = WaitForNoBUSY();
	if(status != ERR_NOERR)
		return status;

	WriteSectorCount(count);
	WriteLBA(lba);

	WriteCommand(WRITE_SECTORS_WITH_RETRY);

	ptr = (unsigned short *)buf;
	do
	{
		status = WaitForDRQ();
		if(status != ERR_NOERR)
			return status;

		for(i=0; i<SECTOR_WORDS; i++)
			WriteData(*ptr++);

	}while(--count);

	return CheckStatus();
}


/*
* name: IDE_GetStatusString()
* parameter: status			---input, status
* return: string.
* description: convert status code to corresponding string.
*/
const char* IDE_GetStatusString(unsigned long status)
{
	int i, cnt;

	status &= 0xff;
	if(status)
	{
		for(i=0; i<sizeof(char); i++)
		{
			if(status & 0x1)
				return StaString[i];
			status >>= 1;
		}
	}

	return 0;
}


/*
* name: IDE_GetErrorString()
* parameter: err			---input, drive error code.
* return: string.
* description: convert error code to corresponding string.
*/
const char* IDE_GetErrorString(enum DrvErr err)
{
	int i = (err & 0x7f);

	if(i > 0 && i <= 5)
	{
		i--;
		if(err & 0x80)
			i += 5;
		return ErrString[i];
	}
	
	return 0;
}

⌨️ 快捷键说明

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