📄 cfc_ata.c
字号:
/****************************************************************************
Project: DSC
Module: File System
File: cfc_ata.c
Description: Here to provide basic ATA services to the upper layer of the
FS module
Date: Feb 28, 2000
Author: Zhu Yao Zong
copyright by China Digipro, all rights reserved
=====================================================
I/O cache support function added into the system.
Aug 18, 2000
Zhu, Yaozong
=====================================================
Porting from DSC11->C549 to DSC21->ARM7TDMI architecture
Oct 23, 2000
Zhu, Yaozong
*****************************************************************************/
/***************************************************************************
Project: DSC
Module: File System
File: cfc_ata.h
Description: Here defines CFC memory mapped I/O access points and some constants
Date: Feb 28, 2000
Author: Zhu Yao Zong
copyright by China Digipro, all rights reserved
=====================================================
I/O cache support function added into the system.
Aug 18, 2000
Zhu, Yaozong
=====================================================
Porting from DSC11->C549 to DSC21->ARM7TDMI architecture
Oct 23, 2000
Zhu, Yaozong
*****************************************************************************/
//ARM_IDLECT2
#define EN_XORPC_CK 0x002
#define EN_GPIOCK (1<<9)
//clock reset peripheral pin
extern volatile unsigned short * pARM_RSTCT2;
extern volatile unsigned short * pARM_IDLECT2;
//ARM_RSTCT2
#define PER_EN 0x01;
#define ATA_WORDS_PER_SECTOR 0x0100
#define ATA_INVALID_SECTOR 0xFFFFFFFFL
#define ATA_INVALID_WORD 0xFFFF
#define COMMAND STATUSCOMMAND /* when write */
#define STATUS STATUSCOMMAND /* when read */
#define ERROR ERRFEATURE /* when read */
#define FEATURE ERRFEATURE /* when write */
/* CFC ATA Command Set */
#define ATA_EXECUTEDEVICEDIAGNOSTIC 0x90
#define ATA_CHECKPOWERMODE 0x98
#define ATA_READSECTOR 0x20
#define ATA_WRITESECTOR 0x30
#define ATA_IDENTIFY 0xEC
#define ATA_IDLE 0x97
#define ATA_IDLEIMMEDIATE 0xE1
#define ATA_READBUFFER 0xE4
#define ATA_READVERIFYSECTORS 0x40
#define ATA_REQUESTSENSE 0x03
#define ATA_SETFEATURES 0xEF
#define ATA_STANDBY 0x96
#define ATA_STANDBYIMMEDIATE 0x94
#define LBA_DRIVE_0 0xE0 /* Drive/Head(LBA 27-24) Register Layout:
D7 D6 D5 D4 D3 D2 D1 D0
|1 |LBA|1 |Drv|HS3|HS2|HS1|HS0| */
#define FPGA_INTMASK_ADDRESS 0x08000008
#define FPGA_INTSTAT_ADDRESS 0x08000006
#define FPGA_INTCLEAR_ADDRESS 0x08000000
struct ata_task_file_struct {
volatile unsigned short datareg;
volatile unsigned short errfeature;
volatile unsigned short sectorcount;
volatile unsigned short sectornum;
volatile unsigned short cylinderlow;
volatile unsigned short cylinderhigh;
volatile unsigned short lbadrivehead;
volatile unsigned short statuscommand;
//volatile unsigned short unused[6];
//volatile unsigned short altstatusdevcontrol;
};
unsigned short *fpga_intmask = (unsigned short*)FPGA_INTMASK_ADDRESS;
unsigned short *fpga_intstat = (unsigned short*)FPGA_INTSTAT_ADDRESS;
unsigned short *fpga_intclear = (unsigned short*)FPGA_INTCLEAR_ADDRESS;
struct ata_task_file_struct *cfif = (void *)0;
static unsigned int CheckforATAErrorSector( void )
{
unsigned int onErrorSectorNO;
if ( ( cfif->statuscommand & 0x01) != 0 )
{
onErrorSectorNO = ((unsigned int)cfif->lbadrivehead & 0x0000000FL) << 24;
onErrorSectorNO += ((unsigned int)cfif->cylinderhigh & 0x000000FFL) << 16;
onErrorSectorNO += ((unsigned int)cfif->cylinderlow & 0x000000FFL) << 8;
onErrorSectorNO += (unsigned int)cfif->sectornum & 0x000000FFL;
return onErrorSectorNO;
}
else
return 0xFFFFFFFFL;
}
#define WaitUntilCFCReady if(WaitUntilCFC_Ready()) return -1
static int WaitUntilCFC_Ready(void)
{
unsigned char status;
int i= 0;
status = cfif->statuscommand;
//status = STATUSCOMMAND;
/* Further error processing may be added. Zhu, Yaozong Jul 18, 2000 */
while ( (status&0x80 ) && (i < 1000000)) {
status = cfif->statuscommand; // Bit 7 of status register indicates
i ++;
}
if(i == 1000000) {
// printf("WaitUntilCFC_Ready = %d",i);
return -1;
}
return 0;
}
short IdentifyDrive( unsigned short* buffer )
{
unsigned short i;
WaitUntilCFCReady;
cfif->lbadrivehead = LBA_DRIVE_0;
cfif->statuscommand = ATA_IDENTIFY;
WaitUntilCFCReady;
for( i = 0; i < ATA_WORDS_PER_SECTOR; i++ )
{
buffer[i] = cfif->datareg;
}
return 0;
}
short ReadSectors( unsigned int SectorAddress, unsigned char SectorCount, unsigned short* buffer )
{
unsigned short i,j;
unsigned int ErrorSector;
unsigned short CurrentWordinBuffer;
WaitUntilCFCReady;
cfif->lbadrivehead = LBA_DRIVE_0|(unsigned char)((SectorAddress&0x0F000000L)>>24); /* LBA addressing mode, drive 0 */
cfif->cylinderhigh = (unsigned char)((SectorAddress&0x00FF0000L)>>16);
cfif->cylinderlow = (unsigned char)((SectorAddress&0x0000FF00L)>>8);
cfif->sectornum = (unsigned char)(SectorAddress&0x000000FFL);
cfif->sectorcount = SectorCount;
cfif->statuscommand = ATA_READSECTOR;
CurrentWordinBuffer = 0;
for( i = 0; i<SectorCount; i ++ )
{
WaitUntilCFCReady;
for( j = 0; j < ATA_WORDS_PER_SECTOR; j++ )
{
buffer[CurrentWordinBuffer++] = cfif->datareg;
//buffer[CurrentWordinBuffer++] = *((unsigned short*)0x04000e08); // When a10 is high, all memory references duplicate data port;
}
}
ErrorSector = CheckforATAErrorSector();
if ( ErrorSector != 0xFFFFFFFFL ) /* Bad sector */
{
return -1;
}
return 0;
}
short WriteSectors( unsigned int SectorAddress, unsigned char SectorCount, unsigned short* buffer )
{
unsigned short i,j;
unsigned int ErrorSector;
unsigned short CurrentWordinBuffer;
WaitUntilCFCReady;
cfif->lbadrivehead = LBA_DRIVE_0|(unsigned char)((SectorAddress&0x0F000000L)>>24); /* LBA addressing mode, drive 0 */
cfif->cylinderhigh = (unsigned char)((SectorAddress&0x00FF0000L)>>16);
cfif->cylinderlow = (unsigned char)((SectorAddress&0x0000FF00L)>>8);
cfif->sectornum = (unsigned char)(SectorAddress&0x000000FFL);
cfif->sectorcount = SectorCount;
cfif->statuscommand = ATA_WRITESECTOR;
CurrentWordinBuffer = 0;
for( i = 0; i<SectorCount; i ++ )
{
WaitUntilCFCReady;
for( j = 0; j<ATA_WORDS_PER_SECTOR; j++ )
{
cfif->datareg = buffer[CurrentWordinBuffer++];
}
}
ErrorSector = CheckforATAErrorSector();
if ( ErrorSector != 0xFFFFFFFFL ) /* Bad sector */
{
return -2;
}
return 0;
}
unsigned short buffer[256*8];
unsigned short *cfif_reset = (unsigned short*)0x04800010;
int CF_test(int flag)
{
static unsigned int count = 0;
unsigned int i;
/* Set CF insterrupt mask */
if(flag == 0) {
cfif = (struct ata_task_file_struct*)0x04000000;
*fpga_intmask = 0x0008;
}else{
cfif = (struct ata_task_file_struct*)0x04800000;
*fpga_intmask = 0x0004;
}
/* Set HD insterrupt mask */
//*fpga_intmask = 0x0008;
*cfif_reset = 0;
for(i = 0; i < 1000; i++)
;
*cfif_reset = 1;
WaitUntilCFCReady;
if( IdentifyDrive((unsigned short*)buffer ))
return -1;
for(i = 0; i < 256; i++)
buffer[i] = i|0xa500;
if( WriteSectors( 1, 1, (unsigned short*)buffer ) )
return -1;
for(i = 0; i < 256; i++)
buffer[i] = 0;
if( ReadSectors( 1, 8, (unsigned short*)buffer ) )
return -1;
printf("buffer[0] is 0x%x. buffer[1] is 0x%x\n", buffer[0], buffer[1]);
//while(1) { ReadSectors( 1, 8, (unsigned short*)buffer );
// count += 8;
//}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -