📄 ata.c
字号:
#include <reg51.h>
#include <intrins.h>
#include <stdio.h >
#include "include\Typedef.h"
#include "include\AT89C51SND.h"
#include "include\config.h"
#include "include\constant.h"
#include "include\global.h"
#include "include\macro.h"
#include "include\external.h"
#include "include\gpio.h"
/**************************************************************************
* C O N S T A N T S
*************************************************************************/
/**************************************************************************
* M A C R O S
*************************************************************************/
/**************************************************************************
* D A T A T Y P E S
*************************************************************************/
/**************************************************************************
* G L O B A L D A T A
*************************************************************************/
/**************************************************************************
* Function Name:
*
* Descriptions:
*
* Arguments:
*
* Returns: None
**************************************************************************/
void ATAInit()
{
gATACapacity = 0;
ATA_RESET();
msDelay();
msDelay();
msDelay();
WriteReg(DRV_HEAD,0xa0);
ATAWaitCardReady();
gATACapacity = ATACapacity();
printf("%08lu\n",gATACapacity);
}
/**************************************************************************
* Function Name:
*
* Descriptions:
*
* Arguments:
*
* Returns: None
**************************************************************************/
void ATA_RESET(void)
{
P4_5=0;
msDelay();
msDelay();
msDelay();
P4_5=1;
}
/**************************************************************************
* Function Name:
*
* Descriptions:
*
* Arguments:
*
* Returns: None
**************************************************************************/
UINT8 ATAWaitDataReady(void)
{
UINT8 temp;
gTB = 0;
do { temp=ReadReg(ALT_STATUS);
if ( (temp & 0x01)||(gTB>=10000) ) return temp;
} while((temp & 0x89)!=0x08); //[11/08]
gTB = 0;
do {
temp=ReadReg(STATUS);
if ( (temp & 0x01)||(gTB>=10000) ) return temp;
} while((temp & 0x89)!=0x08); //[11/08]
return 0;
}
/**************************************************************************
* Function Name:
*
* Descriptions:
*
* Arguments:
*
* Returns: None
**************************************************************************/
/*wait BSY=0,DRDY=1*/
UINT8 ATAWaitCardReady()
{
UINT8 temp;
do {
temp=ReadReg(ALT_STATUS);
} while((temp & 0xC0)!=0x40);
do {
temp=ReadReg(STATUS);
} while((temp & 0xC0)!=0x40);
return 0;
}
/**************************************************************************
* Function Name:ATAReadID
*
* Descriptions:
*
* Arguments:
*
* Returns: None
**************************************************************************/
void ATAReadID(void)
{
ATAWaitCardReady();
WriteReg(DRV_HEAD,0XA0);
WriteReg(COMMAND,0XEC);
ATAWaitDataReady();
Read1Sector();
ATAWaitCardReady();
}
/**************************************************************************
* Function Name:ATACapacity
*
* Descriptions:
*
* Arguments:
*
* Returns: None
**************************************************************************/
UINT32 ATACapacity(void)
{
LongByte lbTotal ;
ATAReadID() ;
lbTotal.BYTE.B3=DMA_BUF[123];
lbTotal.BYTE.B2=DMA_BUF[122];
lbTotal.BYTE.B1=DMA_BUF[121];
lbTotal.BYTE.B0=DMA_BUF[120];
return(lbTotal.ULONG);
}
/**************************************************************************
* Function Name:ATAGetCapacity
*
* Descriptions:
*
* Arguments:
*
* Returns: None
**************************************************************************/
UINT32 ATAGetCapacity(void)
{
return gATACapacity;
}
/**************************************************************************
* Function Name:ATAMultipleRead
*
* Descriptions:
*
* Arguments:
*
* Returns: None
**************************************************************************/
UINT8 ATAMultipleRead(UINT32 u32SectorNo)
{
UINT8 i,j,Fcnt;
UINT16 bcnt=0;
bit begin_ping_pong=0;
union
{
UINT32 sn;
UINT8 secno[4];
} s;
s.sn=u32SectorNo;
if (ATAWaitCardReady()) {
return 1;
}
WriteReg(DRV_HEAD,((s.secno[0] & 0x0f) | 0xE0));
WriteReg(CYH,(s.secno[1]));
WriteReg(CYL,(s.secno[2]));
WriteReg(SN, (s.secno[3]));
WriteReg(SC,gSectors);
WriteReg(COMMAND,0X20);
for(i=0;i<gSectors;i++)//how many sector must to read
{
if ( ATAWaitDataReady() ) return 1;//WAIT BSY=0,DRQ=1.
Set_Adr_DATA();
P0 = 0xff;
P2 = 0xff;
bcnt=0;
for(j=0;j<8;j++)//64BYTE Packetsize*8
{
for(Fcnt=0;Fcnt<64;Fcnt++)
{
P3_7 = 0;
UEPDATX = P0;//DATA7~0
Fcnt++;
UEPDATX = P2;//DATA15~8
P3_7 = 1;
}
Usb_set_TXRDY_bit();
while (!Usb_tx_complete_bit()){}
Usb_clear_TXCMPL_bit(); //ack transfer
gCBWDataLen=gCBWDataLen-64;
}
}
if (ATAWaitCardReady()) return 1;
return 0;
}
/**************************************************************************
* Function Name:ATAMultipleWrite
*
* Descriptions:
*
* Arguments:
*
* Returns: None
**************************************************************************/
UINT8 ATAMultipleWrite(UINT32 u32SectorNo)
{
UINT8 i,j,Fcnt;
UINT16 bcnt=0;
union
{
UINT32 sn;
UINT8 secno[4];
} s;
s.sn=u32SectorNo;
if (ATAWaitCardReady()) return 1;
WriteReg(DRV_HEAD,((s.secno[0] & 0x0f) | 0xE0));
WriteReg(CYH,(s.secno[1]));
WriteReg(CYL,(s.secno[2]));
WriteReg(SN, (s.secno[3]));
WriteReg(SC,gSectors);
WriteReg(COMMAND,0X30);
for(i=0;i<gSectors;i++)
{
if(i>0){
if ( ATAWaitDataReady() ) {return 1; }
}
Set_Adr_DATA();
for(j=0;j<8;j++){//collect one sector
while(!(RXOUTB0||RXOUTB1));
for(Fcnt=0;Fcnt<64;Fcnt++)
{
P3_6=0;
P0=UEPDATX;//DATA7~0
Fcnt++;
P2=UEPDATX;//DATA15~8
P3_6=1;
}
UEPSTAX=UEPSTAX & (~0x42);
}
}
if (ATAWaitCardReady()) return 1;
return 0;
}
/**************************************************************************
* Function Name:ATAIsReady
*
* Descriptions:
*
* Arguments:
*
* Returns: None
**************************************************************************/
UINT8 ATAIsReady(void)
{
return(1); // ATA_RDY
}
/**************************************************************************
* Function Name:WriteReg
*
* Descriptions:
*
* Arguments:
*
* Returns: None
**************************************************************************/
void WriteReg(UINT8 reg,UINT8 Data)
{
if(reg==DRV_HEAD)
Set_Adr_DRV_HEAD()
else if(reg==COMMAND)
Set_Adr_COMMAND()
else if(reg==DEV_CTR)
Set_Adr_DEV_CTR()
else if(reg==CYL)
Set_Adr_CYL()
else if(reg==CYH)
Set_Adr_CYH()
else if(reg==SN)
Set_Adr_SN()
else if(reg==SC)
Set_Adr_SC()
P0=Data;
_nop_();
_nop_();
_nop_();
P3_6=0;
msDelay();
P3_6=1;
_nop_();
_nop_();
_nop_();
}
/**************************************************************************
* Function Name:ReadReg
*
* Descriptions:
*
* Arguments:
*
* Returns: None
**************************************************************************/
UINT8 ReadReg(UINT8 Reg)
{
UINT8 temp;
if(Reg==STATUS)
Set_Adr_STATUS()
else if(Reg==ALT_STATUS)
Set_Adr_ALT_STATUS()
P0=0xff;
P3_7=0;
msDelay();
temp=P0;
msDelay();
P3_7=1;
return temp;
}
/**************************************************************************
* Function Name:Read1Sector
*
* Descriptions:
*
* Arguments:
*
* Returns: None
**************************************************************************/
void Read1Sector(void)
{ UINT16 bcnt;
Set_Adr_DATA();
for(bcnt=0;bcnt<=255;bcnt++)
{
P3_7=0;
_nop_();
_nop_();
DMA_BUF[(bcnt<<1)]=P0;
DMA_BUF[(bcnt<<1)+1]=P2;
P3_7=1;
_nop_();
_nop_();
}
}
/**************************************************************************
* Function Name:msDelay
*
* Descriptions:
*
* Arguments:
*
* Returns: None
**************************************************************************/
void msDelay() // in ms.
{
UINT8 j;
for (j=0; j<200 ; j++) {
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -