📄 ata._c
字号:
#include <iom128v.h>
#include <string.h>
#include <stdio.h>
#include <macros.h>
#include "ata.h"
#include "generic.h"
#include "remote.h"
#define debug
#define debugport 1
//******************************************************************
//* INITIALIZE HARDWARE FOR ATA DRIVER
//*
//*
//******************************************************************
int init_ata(unsigned char device)
{
unsigned int word_read,i,j;
ata_databus_in;
PORT_ATA_IO_CNTL_DDR = 0xff;
PORT_ATA_IO_CNTL = ATA_IO_HIZ;
PORT_ATA_RST_CNTL_DDR |= ATA_RESET;
ata_hard_reset();
while (!ready & busy);
ata_select_device(device);
while (!ready & busy);
ata_write_byte(ATA_IO_CMD,CMD_RECALIBRATE);
while (busy);
ata_write_byte(ATA_IO_SECTORCNT,60); // Sleep after 5 min
while (busy);
ata_write_byte(ATA_IO_CMD,CMD_STANDBY2);
while (busy);
return 1;
}
//******************************************************************
//* PERFORM HARDWARE RESET
//* This routine toggles ATA RESET line low for 10ms.
//*
//******************************************************************
void ata_hard_reset(void)
{
ata_databus_in;
PORT_ATA_RST_CNTL &= ~ATA_RESET;
delay_ms(10);
PORT_ATA_RST_CNTL |= ATA_RESET;
delay_ms(10);
}
//******************************************************************
//* SELECT ATA DEVICE
//* This routine defaults to Drive 0 as the target drive.
//*
//******************************************************************
void ata_select_device(unsigned char device)
{
switch (device)
{
case 0x00:
ata_write_byte(ATA_IO_DEVICE_HEAD,ATA_DH_DEV0);
break;
case 0x01:
ata_write_byte(ATA_IO_DEVICE_HEAD,ATA_DH_DEV1);
break;
default:
ata_write_byte(ATA_IO_DEVICE_HEAD,ATA_DH_DEV0);
break;
}
}
//******************************************************************
//* WRITE WORD TO ATA DEVICE
//*
//* Mapping : D0-PA0,D1-PA2,D2-PA4,D3-PA6,D4-PC7,D5-PC5,D7-PC3,D7-PC1
//* D8-PC0,D9-PC2,D10-PC4,D11-PC6,D12-PA7,D13-PA5,D14-PA3,D15-PA1
//******************************************************************
void ata_write_word(unsigned char reg,unsigned int wordout)
{
WDR();
PORT_ATA_IO_CNTL = reg;
ata_databus_out;
PORT_ATA_DATA1_OUT = 0x00;
PORT_ATA_DATA2_OUT = 0x00;
if (wordout & 0x0001) PORT_ATA_DATA1_OUT |= 0x01;
if (wordout & 0x0002) PORT_ATA_DATA1_OUT |= 0x04;
if (wordout & 0x0004) PORT_ATA_DATA1_OUT |= 0x10;
if (wordout & 0x0008) PORT_ATA_DATA1_OUT |= 0x40;
if (wordout & 0x0010) PORT_ATA_DATA2_OUT |= 0x80;
if (wordout & 0x0020) PORT_ATA_DATA2_OUT |= 0x20;
if (wordout & 0x0040) PORT_ATA_DATA2_OUT |= 0x08;
if (wordout & 0x0080) PORT_ATA_DATA2_OUT |= 0x02;
if (wordout & 0x0100) PORT_ATA_DATA2_OUT |= 0x01;
if (wordout & 0x0200) PORT_ATA_DATA2_OUT |= 0x04;
if (wordout & 0x0400) PORT_ATA_DATA2_OUT |= 0x10;
if (wordout & 0x0800) PORT_ATA_DATA2_OUT |= 0x40;
if (wordout & 0x1000) PORT_ATA_DATA1_OUT |= 0x80;
if (wordout & 0x2000) PORT_ATA_DATA1_OUT |= 0x20;
if (wordout & 0x4000) PORT_ATA_DATA1_OUT |= 0x08;
if (wordout & 0x8000) PORT_ATA_DATA1_OUT |= 0x02;
ata_write_pulse;
ata_databus_in;
}
//******************************************************************
//* WRITE BYTE TO ATA DEVICE
//*
//*
//******************************************************************
void ata_write_byte(unsigned char reg,unsigned char byteout)
{
ata_write_word(reg,(unsigned int)byteout);
}
//******************************************************************
//* READ WORD FROM ATA DEVICE
//*
//*
//* Mapping : D0-PA0,D1-PA2,D2-PA4,D3-PA6,D4-PC7,D5-PC5,D7-PC3,D7-PC1
//* D8-PC0,D9-PC2,D10-PC4,D11-PC6,D12-PA7,D13-PA5,D14-PA3,D15-PA1
//******************************************************************
unsigned int ata_read_word(unsigned char reg)
{
unsigned int wordin = 0;
WDR();
PORT_ATA_IO_CNTL = reg;
ata_databus_in;
PORT_ATA_IO_CNTL &= ~ATA_IOR;
delay_us(1);
if (PORT_ATA_DATA1_IN & 0x01) wordin |= 0x0001;
if (PORT_ATA_DATA1_IN & 0x02) wordin |= 0x8000;
if (PORT_ATA_DATA1_IN & 0x04) wordin |= 0x0002;
if (PORT_ATA_DATA1_IN & 0x08) wordin |= 0x4000;
if (PORT_ATA_DATA1_IN & 0x10) wordin |= 0x0004;
if (PORT_ATA_DATA1_IN & 0x20) wordin |= 0x2000;
if (PORT_ATA_DATA1_IN & 0x40) wordin |= 0x0008;
if (PORT_ATA_DATA1_IN & 0x80) wordin |= 0x1000;
if (PORT_ATA_DATA2_IN & 0x01) wordin |= 0x0100;
if (PORT_ATA_DATA2_IN & 0x02) wordin |= 0x0080;
if (PORT_ATA_DATA2_IN & 0x04) wordin |= 0x0200;
if (PORT_ATA_DATA2_IN & 0x08) wordin |= 0x0040;
if (PORT_ATA_DATA2_IN & 0x10) wordin |= 0x0400;
if (PORT_ATA_DATA2_IN & 0x20) wordin |= 0x0020;
if (PORT_ATA_DATA2_IN & 0x40) wordin |= 0x0800;
if (PORT_ATA_DATA2_IN & 0x80) wordin |= 0x0010;
PORT_ATA_IO_CNTL |= ATA_IOR;
return wordin;
}
//******************************************************************
//* READ BYTE FROM ATA DEVICE
//*
//*
//*
//******************************************************************
unsigned char ata_read_byte(unsigned char reg)
{
return (unsigned char)(ata_read_word(reg) & 0x00ff);
}
//******************************************************************
//* CHECK ATA READY BIT
//* Checks READY status bit.
//* Returns 1 if device is ready.
//******************************************************************
unsigned char ata_rdy(void)
{
if (ata_read_byte(ATA_IO_STATUS) & ATA_STAT_RDY) return 1;
else return 0;
}
//******************************************************************
//* CHECK ATA BUSY BIT
//* Checks READY status bit.
//* Returns 1 if device is busy.
//******************************************************************
unsigned char ata_bsy(void)
{
if (ata_read_byte(ATA_IO_STATUS) & ATA_STAT_BSY) return 1;
else return 0;
}
//******************************************************************
//* CHECK ATA DRQ BIT
//* Checks READY status bit.
//* Returns 1 if device is requesting service.
//******************************************************************
unsigned char ata_drq(void)
{
if (ata_read_byte(ATA_IO_STATUS) & ATA_STAT_DRQ) return 1;
else return 0;
}
//******************************************************************
//* CHECK ATA ERROR BIT
//* Checks READY status bit.
//* Returns 1 if device is reporting an error condition.
//******************************************************************
unsigned char ata_err(void)
{
if (ata_read_byte(ATA_IO_STATUS) & ATA_STAT_ERR) return 1;
else return 0;
}
//******************************************************************
//* READ A PART of SECTOR
//* device = 0x00 or 0x01
//*
//******************************************************************
void ata_read_sector_byte(unsigned char device, unsigned long lbasector,
unsigned int from, unsigned int qte,
unsigned char *ptr)
{
unsigned int i,j,word;
lbasector &= 0x0FFFFFFF;
switch (device)
{
case 0x00:
ata_write_byte(ATA_IO_DEVICE_HEAD,lbasector >> 24 | 0xE0);
break;
case 0x01:
ata_write_byte(ATA_IO_DEVICE_HEAD,lbasector >> 24 | 0xF0);
break;
default:
ata_write_byte(ATA_IO_DEVICE_HEAD,lbasector >> 24 | 0xE0);
break;
}
while(busy);
ata_write_byte(ATA_IO_CYL_H,lbasector >> 16);
while(busy);
ata_write_byte(ATA_IO_CYL_L,lbasector >> 8);
while(busy);
ata_write_byte(ATA_IO_SECTORNUM,lbasector);
while(busy);
ata_write_byte(ATA_IO_SECTORCNT,0x01);
while(busy);
ata_write_byte(ATA_IO_CMD,CMD_READ_SECTORS);
while(busy);
while(!drq);
j = 0;
for (i=0;i<256;i++)
{
word = ata_read_word(ATA_IO_DATA);
if ((j >= from) && (j < (from + qte))) *ptr++ = (unsigned char)(word);
j++;
if ((j >= from) && (j < (from + qte))) *ptr++ = (unsigned char)(word >> 8);
j++;
while(busy);
}
}
//******************************************************************
//* WRITE A SECTOR
//* device = 0x00 or 0x01
//*
//******************************************************************
void ata_write_sector(unsigned char device, unsigned long lbasector, unsigned char *ptr)
{
unsigned int i;
lbasector &= 0x0FFFFFFF;
switch (device)
{
case 0x00:
ata_write_byte(ATA_IO_DEVICE_HEAD,lbasector >> 24 | 0xE0);
break;
case 0x01:
ata_write_byte(ATA_IO_DEVICE_HEAD,lbasector >> 24 | 0xF0);
break;
default:
ata_write_byte(ATA_IO_DEVICE_HEAD,lbasector >> 24 | 0xE0);
break;
}
while(busy);
ata_write_byte(ATA_IO_CYL_H,lbasector >> 16);
while(busy);
ata_write_byte(ATA_IO_CYL_L,lbasector >> 8);
while(busy);
ata_write_byte(ATA_IO_SECTORNUM,lbasector);
while(busy);
ata_write_byte(ATA_IO_SECTORCNT,0x01);
while(busy);
ata_write_byte(ATA_IO_CMD,CMD_WRITE_SECTORS);
while(busy);
while(!drq);
for (i=0;i<256;i++)
{
ata_write_word(ATA_IO_DATA,0x5555); //(unsigned int)(*(ptr+1)<<8)+*ptr);
ptr += 2;
while(busy);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -