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

📄 idelib.c

📁 武汉创维特ARM7实验箱的全部源代码
💻 C
字号:
#include "44b.h"
#include "44blib.h"

#define IDE_CONTROL_ADDR       0x0a000006
#define IDE_CONTROL_IOIS_ADDR  0x0a000004
#define IDE_CONTROL_CS_ADDR    0x0a080000

#define IDE_CONTROL_MASK_POWER  (1<<4)
#define IDE_CONTROL_MASK_IOIS   (1<<3)
#define IDE_CONTROL_MASK_CS     (0x3<<2)

#define IDE_COMMAND_BASE   0x020C0000

#define inp(port) (*(unsigned char *)(port))
#define inw(port) (*(unsigned short *)(port))
#define outp(port, value) (*(unsigned char *)(port))=value

char *getascii (unsigned short in_data [], unsigned short off_start, unsigned short off_end);

int ide_ctrl_value = 0x0;
int ide_ctrl_iois_value = 0x0;
int ide_ctrl_cs_value = (0x0 << 2);

void ide_iois_ctrl(int biois)
{
	if(biois)
	{
		ide_ctrl_iois_value |= IDE_CONTROL_MASK_IOIS;
	}else
	{
		ide_ctrl_iois_value &= ~IDE_CONTROL_MASK_IOIS;
	}
	*(unsigned char *)IDE_CONTROL_IOIS_ADDR = ide_ctrl_iois_value;
}

void ide_rst_ctrl(int brst)
{
	if(brst)
	{
		ide_ctrl_value |= IDE_CONTROL_MASK_POWER;
	}else
	{
		ide_ctrl_value &= ~IDE_CONTROL_MASK_POWER;
	}
	*(unsigned char *)IDE_CONTROL_ADDR = ide_ctrl_value;
}

void ide_cs_ctrl(int cs)
{
	ide_ctrl_cs_value &= ~IDE_CONTROL_MASK_CS;
	ide_ctrl_cs_value |= (cs<<2);
	*(unsigned char *)IDE_CONTROL_CS_ADDR = ide_ctrl_cs_value;
}

char *getascii (unsigned short in_data [], unsigned short off_start, unsigned short off_end)
{
	static char ret_val [255];
	int loop, loop1;
	
	for (loop = off_start, loop1 = 0; loop <= off_end; loop++)
    {
		ret_val [loop1++] = (char) (in_data [loop] / 256);  /* Get High byte */
		ret_val [loop1++] = (char) (in_data [loop] % 256);  /* Get Low byte */
    }
	ret_val [loop1] = '\0';  /* Make sure it ends in a NULL character */
	return (ret_val);
}

//Control Block Registers 
#define REG_ALT_STATUS			(IDE_CONTROL_BASE+0x04)		// R
#define REG_DEVICE_CONTROL		(IDE_CONTROL_BASE+0x04)		// W
#define REG_DRIVE_ADDRESS		(IDE_CONTROL_BASE+0x07)		// R

//Command Block Registers
#define REG_DATA				(IDE_COMMAND_BASE+0x00)		// RW
#define REG_ERROR				(IDE_COMMAND_BASE+0x01)		// RW
#define REG_SECTOR_COUNT		(IDE_COMMAND_BASE+0x02)		// RW
#define REG_SECTOR_NUMBER		(IDE_COMMAND_BASE+0x03)		// RW
#define REG_LBA_BITS_00_07		(IDE_COMMAND_BASE+0x03)		// RW
#define REG_CYLINDER_LOW		(IDE_COMMAND_BASE+0x04)		// RW
#define REG_LBA_BITS_08_15		(IDE_COMMAND_BASE+0x04)		// RW
#define REG_CYLINDER_HIGH		(IDE_COMMAND_BASE+0x05)		// RW
#define REG_LBA_BITS_16_23		(IDE_COMMAND_BASE+0x05)		// RW
#define REG_DRIVE_HEAD			(IDE_COMMAND_BASE+0x06)		// RW
#define REG_LBA_BITS_24_27		(IDE_COMMAND_BASE+0x06)		// RW
#define REG_STATUS				(IDE_COMMAND_BASE+0x07)		// R
#define REG_COMMAND				(IDE_COMMAND_BASE+0x07)		// W

// Status consts
#define IDE_ST_BUSY				0x80
#define IDE_ST_DRDY				0x40
#define IDE_ST_DWF				0x20
#define IDE_ST_DSC				0x10
#define IDE_ST_DRQ				0x08
#define IDE_ST_CORR				0x04
#define IDE_ST_IDX				0x02
#define IDE_ST_ERR				0x01

// Commands
#define IDE_CMD_READ_DMA		0xc8
#define IDE_CMD_READ_DMA1		0xc9
#define IDE_CMD_READ_LONG		0x22
#define IDE_CMD_READ_LONG1		0x23
#define IDE_CMD_READ_MULTI		0xc4
#define IDE_CMD_READ_SECTORS	0x20
#define IDE_CMD_READ_SECTORS1	0x21
#define IDE_CMD_READ_VERIFY_SECTORS		0x40
#define IDE_CMD_READ_VERIFY_SECTORS1	0x41

void ide_read_sector(
		unsigned char 	sec_cnt, 
		unsigned char 	sec_num, 
		unsigned short 	clyn, 
		unsigned char 	head, 
		unsigned char* 	p_data)
{
	int 			index;
	unsigned char 	status;
	unsigned char*	p_buffer = p_data;
	
	// switch to command block registers and wait for no busy
	ide_cs_ctrl(2);
	Delay(100);
	
	rBWSCON &= (~(0xf<<4));
	rBWSCON |= (0x01<<4);
		
	Delay(400);
	
	/* Wait for controller not busy */
	do
	{
		status = inp (IDE_COMMAND_BASE + 14);
	}while (status & 0x80);
	
	/* step 1
	a) 	The host writes any required parameters to the Features, Sector Count, 
    	Sector Number, Cylinder and Drive/Head registers.*/
    outp(REG_SECTOR_COUNT, 	sec_cnt);
    outp(REG_SECTOR_NUMBER, sec_num);
    
    outp(REG_CYLINDER_LOW, 	clyn&0x00ff);
    outp(REG_CYLINDER_HIGH, (clyn>>8)&0x00ff);
    
    outp(REG_DRIVE_HEAD, 	0xa|(head&0x0f));		// CHS mode and master device
  	
    /* step 2
 	b) 	The host writes the command code to the Command Register. */
 	outp(REG_COMMAND, 		IDE_CMD_READ_SECTORS);
 	
 	/* step 3
 	c) 	The drive sets BSY and prepares for data transfer. */
	/* Wait for controller busy */
	do
	{
		status = inp (IDE_COMMAND_BASE + 14);
	}while (!(status & 0x80));
 	
 	/* step 4
 	d) 	When a sector of data is available, the drive sets DRQ and clears BSY 
    	prior to asserting INTRQ. */
AGAIN:    	
    do
	{
		status = inp (IDE_COMMAND_BASE + 14);
	}while ((status & 0x80));
	
    /* step 5
 	e) 	After detecting INTRQ, the host reads the Status Register, then reads one 
    	sector of data via the Data Register. In response to the Status Register 
    	being read, the drive negates INTRQ.  */
    for (index = 0; index != 512; index += 2) 	/* Read "sector" */
	{
		*p_buffer = inw (REG_DATA);
	}
	
	sec_cnt--;
    	
    /* step 6
 	f) 	The drive clears DRQ. If transfer of another sector is required, the drive 
    	also sets BSY and the above sequence is repeated from d).*/
    if(sec_cnt!=0) goto AGAIN;
}

void dump_data(unsigned char* data, int size)
{
	int loopcnt;
	for (loopcnt = 0; loopcnt < size; loopcnt ++)
	{
		Uart_Printf("0x%02x ", data[loopcnt]);
		if(loopcnt != 0 && (loopcnt % 16 == 0))		
			Uart_Printf("\n");
	}
}

⌨️ 快捷键说明

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