📄 cf卡.txt
字号:
if(gbVerbose)
{
printf("Identify Device:\n");
}
if(cardPresent())
{
#if IDE_DEBUG
printf("IDE_identifyDevice(): card is inserted\n");
#endif
}
else
{
printf("IDE_identifyDevice(): error: CompactFlash card is removed\n");
return -1;
}
/* PIO read/write steps (a) through (c) */
if(PIODataInOrOutPreamble(uiDeviceNumber)) //数据输入输出导言 写入磁头寄存器数值
{
printf("IDE_identifyDevice(): error: PIODataInOrOutPreamble failed.\n");
return -1;
}
/*
* PIO read/write step (d)
* (No input parameters for Identify Device)
*/
/* PIO read/write step (e) */
IDEinterrupt = 0;
IOWR_ALTERA_AVALON_CF_IDE_COMMAND(ide_base, IdentifyDeviceCmd); // IdentifyDeviceCmd = 0xEC, 设备识别指令
/* PIO read/write step (f) */
usleep(1);
/*
* PIO read/write step (g)
*
* Wait for INTRQ. Empirically, I note that after a hardware reset
* (press SW2), it can take an eternity (3.3 s) to get INTRQ here, on the
* Connor drive at least. Use a really long timeout.
*/
if(awaitINTRQ(5000))
{
printf("IDE_identifyDevice(): error: timeout awaiting INTRQ=1\n");
printf("error reg=0x%X\n", IORD_ALTERA_AVALON_CF_IDE_ERROR(ide_base));
return -1;
}
/* PIO read/write step (h) */
usStatus = IORD_ALTERA_AVALON_CF_IDE_STATUS(ide_base);
usStatus = IORD_ALTERA_AVALON_CF_IDE_ALTERNATE_STATUS(ide_base);
/* PIO read/write step (i) */
if(usStatus & StatusRegBitDRQ) //如果读状态寄存器得drq位=1, 传输256组参数信息
{
for(i = 0; i < 256; ++i)
{
usBuffer[i] = IORD_ALTERA_AVALON_CF_IDE_DATA(ide_base);
}
}
else
{
printf("IDE_identifyDevice(): error: DRQ not set in status reg\n");
return -1;
}
/* PIO read/write step (j) */
parseIdentifyDeviceBuffer(usBuffer);//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@看这个函数 解析识别设备参数
return 0;
}
//===============++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/*
* executeDeviceDiagnostic()
*
* Perform standard IDE diagnostic & report any errors along the way.
*/
int executeDeviceDiagnostic(int iDevice)
{
unsigned short usStatus, usError;
/* PIO read/write steps (a) through (c) */
if(PIODataInOrOutPreamble(iDevice))
{
printf("executeDeviceDiagnostic(): PIODataInOrOutPreamble failed.\n");
return -1;
}
IDEinterrupt = 0;
IOWR_ALTERA_AVALON_CF_IDE_COMMAND(ide_base, ExecuteDeviceDiagnostic);
usleep(1);
usStatus = IORD_ALTERA_AVALON_CF_IDE_STATUS(ide_base);
if(StatusRegBitERR & usStatus)
{
printf("executeDeviceDiagnostic(): Error? error register=0x%X\n",
IORD_ALTERA_AVALON_CF_IDE_ERROR(ide_base));
}
/* Wait for BSY=0. This one takes seconds! */
if(awaitBSYZero(3000))
{
printf("executeDeviceDiagnostic(): error: timeout (2) awaiting BSY=0\n");
return -1;
}
/* Wait for INTRQ. */
if(awaitINTRQ(5000))
{
printf("executeDeviceDiagnostic(): error: timeout awaiting INTRQ=1\n");
printf("error reg=0x%X\n", IORD_ALTERA_AVALON_CF_IDE_ERROR(ide_base));
printf("status reg=0x%X\n", IORD_ALTERA_AVALON_CF_IDE_STATUS(ide_base));
return -1;
}
usStatus = IORD_ALTERA_AVALON_CF_IDE_STATUS(ide_base);
usError = IORD_ALTERA_AVALON_CF_IDE_ERROR(ide_base);
if(usStatus & StatusRegBitERR)
{
printf("executeDeviceDiagnostic(): return code: 0x%X\n", 0xFF & usError);
}
else
{
/* The meanings of other than bits 0 and 7 are vendor-specific. */
switch(usError & 0x81)
{
case 0x0:
printf("Device 0 failed, device 1 passed or not present.\n");
break;
case 0x01:
printf("Device 0 passed; device 1 passed or not present.\n");
break;
case 0x80:
printf("Device 0 failed, device 1 failed.\n");
break;
case 0x81:
printf("Device 0 passed, device 1 failed.\n");
break;
default:
printf("unexpected case in executeDeviceDiagnostic()\n");
break;
}
}
return 0;
}
/*
* softwareReset()
*
* Useful for high-level reset of CF device.
*/
int softwareReset(unsigned int uiDeviceNumber)
{
volatile unsigned int uiStartTime;
unsigned int uiSuccess;
/* Select the device to reset. */
if(uiDeviceNumber > 1)
{
printf("softwareReset(): error: invalid device number (%d)\n",
uiDeviceNumber);
return -1;
}
IOWR_ALTERA_AVALON_CF_IDE_DEVICE_HEAD(ide_base,
uiDeviceNumber ? DevHeadRegBitDEV : 0);
/*
* Host sets the SRST bit to 1 in the Device Control register.
* (Note: interrupt is enabled.)
*/
IOWR_ALTERA_AVALON_CF_IDE_DEVICE_CONTROL(ide_base,
(DevControlRegBitSRST | DevControlRegBitNIEN));
/*
* Device 0 sets BSY bit no later than 400ns after detection of SRST=1
* (I give it ~10ms.)
*/
if(awaitBSYOne(100))
{
printf("softwareReset(): error: timeout awaiting BSY=1\n");
return -1;
}
#if IDE_DEBUG
else
{
printf("softwareReset(): found BSY=1\n");
}
#endif
/*
* Device 0 performs hardware init and diag
* - Dev0 may revert to its default condition
* - Dev0 posts diag results to the Error Register
*
* Hmm. How am I supposed to know when the diag results have arrived?
* There seems to be no handshaking, so I'll assume I can set SRST=0 any
* old time.
*/
/* Dev0 waits for the host to set SRST=0. */
IOWR_ALTERA_AVALON_CF_IDE_DEVICE_CONTROL(ide_base, DevControlRegBitNIEN);
/*
* If a device 1 is expected, some lengthy drive-to-drive communication may
* occur. If no device was detected previously, bit 7 of Error Register set
* to 0.
*
* The device sets:
* - Sector Count to 01
* - Sector Number to 01
* - Cylinder Low register to 0
* - Cylinder High register to 0
* - Device/Head register to 0
*
* Device 0 clears the BSY bit when ready to accept commands that do not
* require DRDY to be 1 (no later than 31 seconds from the time that the host
* sets SRST=0).
*/
/* (watch for the BSY=0) */
if(awaitBSYZero(1000))
{
printf("softwareReset(): error: timeout awaiting BSY=0\n");
return -1;
}
#if DEBUG
printf("found BSY=0\n");
#endif
/* Device 0 sets DRDY when ready to accept any command. */
uiSuccess = 0;
uiStartTime = getTime();
while(getTime() - uiStartTime < 1000)
{
if(IORD_ALTERA_AVALON_CF_IDE_ALTERNATE_STATUS(ide_base) & AltStatusRegBitDRDY)
{
uiSuccess = 1;
break;
}
}
if(!uiSuccess)
{
printf("softwareReset(): error: timeout awaiting DRDY=1\n");
return -1;
}
#if DEBUG
printf("softwareReset(): found DRDY=1 after %d ms\r", uiDeltaTime);
#endif
#if DEBUG
/*
* Verify sector count = 1,
* sector number = 1,
* cylinder low = 0,
* cylinder high = 0,
* dev/head reg = 0.
*/
printf("status register: 0x%X\r", IORD_ALTERA_AVALON_CF_IDE_STATUS(ide_base));
printf("sector count: 0x%X\r", IORD_ALTERA_AVALON_CF_IDE_SECTOR_COUNT(ide_base));
printf("sector number: 0x%X\r", IORD_ALTERA_AVALON_CF_IDE_SECTOR_NUMBER(ide_base));
printf("cylinder low: 0x%X\r", IORD_ALTERA_AVALON_CF_IDE_CYLINDER_LOW(ide_base));
printf("cylinder high: 0x%X\r", IORD_ALTERA_AVALON_CF_IDE_CYLINDER_HIGH(ide_base));
printf("device/head: 0x%X\r", IORD_ALTERA_AVALON_CF_IDE_DEVICE_HEAD(ide_base));
#else
if(
(0xFF & IORD_ALTERA_AVALON_CF_IDE_STATUS(ide_base)) != 0x50 ||
(0xFF & IORD_ALTERA_AVALON_CF_IDE_SECTOR_COUNT(ide_base)) != 1 ||
(0xFF & IORD_ALTERA_AVALON_CF_IDE_SECTOR_NUMBER(ide_base)) != 1 ||
(0xFF & IORD_ALTERA_AVALON_CF_IDE_CYLINDER_LOW(ide_base)) != 0 ||
(0xFF & IORD_ALTERA_AVALON_CF_IDE_CYLINDER_HIGH(ide_base)) != 0 ||
(0xFF & IORD_ALTERA_AVALON_CF_IDE_DEVICE_HEAD(ide_base)) != 0 )
{
printf("softwareReset(): error: software reset command failed.\r");
}
else
{
printf("softwareReset(): software reset command succeeded.\r");
}
#endif // IDE_DEBUG
return 0;
}
//=========================IDE_initialize()===========================//
/*
* IDE_initialize()
*
* Bring up IDE/Compact flash interface as follows:
* - Perform write/readback test to IDE registers
* - Register interrupts for compact flash peripheral & IDE device
* - Attempt to identify & initialize device parameters, including CF card
* attributes such as size and PIO mode.
*/
int IDE_initialize()
{
unsigned char ucWrite;
unsigned char ucRead;
int iGood = 1;
/* Is a card even present? */
if( !cardPresent() )
{
printf("IDE_initialize(): error: Compact Flash card not detected.\n");
return -1;
}
/*
* Are we being asked to initialize because someone hot-swapped the CF card?
* If so, best to do a nice long power cycle in the CF peripheral's HAL
* initialization routine.
*/
if( GetMediaChanged() )
{
ClearMediaChanged();
ALTERA_AVALON_CF_INIT( CF, cf ); //函数意思???????????
}
/* Register write/readback test */
for(ucWrite = 0; ucWrite < 10; ++ucWrite)
{
IOWR_ALTERA_AVALON_CF_IDE_SECTOR_NUMBER(ide_base, ucWrite);
ucRead = IORD_ALTERA_AVALON_CF_IDE_SECTOR_NUMBER(ide_base);
if(ucWrite != ucRead)
{
iGood = 0;
printf("IDE_initialize(): error: verify fail: wrote 0x%X, read 0x%X\n",
ucWrite, ucRead);
}
}
if(iGood)
{
if(IDE_getVerbosity())
{
printf("IDE_initialize(): wrote and verified %d values successfully.\n",
ucWrite);
}
}
else
{
printf("IDE_initialize(): error: failed register write/readback test.\n");
return -1;
}
/* Enable card insertion/removal interrupt */
alt_irq_register(ctl_irq, 0, CTLTrapHandler); //can be used to register an interrupt handler.
//If the function is succesful,
//then the requested interrupt will be enabled upon return.
IOWR_ALTERA_AVALON_CF_CTL_CONTROL(ctl_base,
ALTERA_AVALON_CF_CTL_STATUS_POWER_MSK +
ALTERA_AVALON_CF_CTL_STATUS_IRQ_EN_MSK);
/* Enable IDE interrupts */
alt_irq_register(ide_irq, 0, IDETrapHandler);
IOWR_ALTERA_AVALON_CF_IDE_CTL(ctl_base, ALTERA_AVALON_CF_IDE_CTL_IRQ_EN_MSK);
if(IDE_identifyDevice(0)) //初始化进行时 ,开启中断后,对设备状态识别
{
return -1;
}
IDE_initializeDeviceParameters(0,
IDE_getLogicalHeads(),
IDE_getLogicalCylinders(),
IDE_getSectorsPerTrack());
return 0;
}
/*
* IDE_deinitialize()
*
* Turn off powet to compact flash & disable CF & IDE interrupts
*/
int IDE_deinitialize(void)
{
IOWR_ALTERA_AVALON_CF_CTL_CONTROL(ctl_base, 0);
IOWR_ALTERA_AVALON_CF_IDE_CTL(ctl_base, 0);
alt_irq_register(ide_irq, 0, 0);
alt_irq_register(ctl_irq, 0, 0);
return 0;
}
/////////////////////////////////////////////////
//主程序
/////////////////////////////////////////////////
unsigned short data[512],rdata[512];
int main(void)
{
int i;
if (IDE_initialize())
{
printf("Cannot initialize IDE device.\r");
return -1;
}
else
{
printf("IDE Initialized.\n");
}
for(i=0;i<256;i++)
{
data[i]=0xaa;
printf("data[%d]=%0x.\n",i,data[i]);
}
for(i=256;i<512;i++)
{
data[i]=0xcc;
printf("data[%d]=%0x.\n",i,data[i]);
}
writeSectorsLBA(0,313,2,data);
readSectorsLBA(0,313,2,rdata);
for(i=0;i<512;i++)
{
printf("rdata[%d]=%0x.\n",i,rdata[i]);
}
return 0;
}
。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -