📄 cf卡.txt
字号:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "system.h"
#include "sys/alt_alarm.h"
#include "sys/alt_irq.h"
#include "altera_avalon_cf_regs.h"
#include "altera_avalon_cf.h" //这是 ALTERA_AVALON_CF_INIT( CF, cf )的头文件 函数的功能???
#include "altera_avalon_timer.h"
#include "cf_ideutils.h"
#ifndef CF_IDE_BASE
#error This IDE utility requires a CompactFlash Interface component named "cf"
#endif
#if ALT_SYS_CLK_BASE == none_BASE
#error This IDE utility requires a system clock with millisecond frequency
#endif
#define IDE_DEBUG 0
#define getTime() alt_nticks()
#define ctl_base (int*)CF_CTL_BASE
#define ctl_irq (int)CF_CTL_IRQ
#define ide_base (int*)CF_IDE_BASE
#define ide_irq (int)CF_IDE_IRQ
/*
* Evil globals.
*
* Exactly one IDE device is assumed: these globals store parameters of that
* drive.
*/
unsigned short gusLogicalHeads = 0;//磁头
unsigned short gusLogicalCylinders = 0;//柱面
unsigned short gusSectorsPerTrack = 0;//扇区
unsigned short gusPIOmode = 0;
unsigned short gusLBAmode = 0;
unsigned long gulLBAcapacity = 0;//扇区容量!!!
unsigned char gModel[40+1];
volatile int IDEinterrupt = 0;
int gbVerbose = 0; //得到详细的提示标示
int giMediaChanged = 0;
/*
* Access routines for evil globals.//访问程序
*/
int IDE_getLogicalCylinders(void) //柱面
{
return gusLogicalCylinders;
}
int IDE_getLogicalHeads(void) // 磁头
{
return gusLogicalHeads;
}
int IDE_getSectorsPerTrack(void) //扇区
{
return gusSectorsPerTrack;
}
int IDE_getVerbosity(void) //得到详细信息标志!!!!!
{
return gbVerbose;
}
void IDE_setVerbosity(int iVerbosity) //设定详细信息标志
{
gbVerbose = iVerbosity;
}
char* getModel(void)
{
return gModel;
}
int GetMediaChanged(void)
{
return giMediaChanged;
}
void ClearMediaChanged(void)
{
giMediaChanged = 0;
}
int cardPresent(void) //卡状态检测 存在??
{
if( (IORD_ALTERA_AVALON_CF_CTL_STATUS(ctl_base) &
ALTERA_AVALON_CF_CTL_STATUS_PRESENT_MSK) )
{
return 1;
}
else
{
return 0;
}
}
/*
* IDETrapHandler()
*
* Interrupt routine for IDE interface in external compact flash device. The
* IDE status register must be read to clear the interrupt.//读状态寄存器来采伐中断
*/
void IDETrapHandler(void* context, alt_u32 id)
{
IORD_ALTERA_AVALON_CF_IDE_STATUS(ide_base);
IDEinterrupt = 1;
}
/*
* CTLTrapHandler() //ctl**处理者
*
* Interrupt routine for compact flash peripheral in FPGA. //外围设备的中断程序
*
* This is really a card removal interrupt handler -- when someone removes the
* card, disable control and IDE interrupts -- we don't want interrupts from
* strange CF cards affecing the system until we're ready. Application-level
* software must re-initialize the interface & re-enable these interrupts.
*
* We'll kindly set giMediaChanged so that such application-level software can
* can attempt to re-initialize CF, if it wants to do so.
*/
void CTLTrapHandler(void* context, alt_u32 id)
{
giMediaChanged = 1;
if(!cardPresent()) //检测 卡不存在
{
IDE_deinitialize();//ide 初始化
printf("CompactFlash removed\n"); //输出cf移除命令
}
}
/*
* awaitBSYZeroOrINTRQ()
*
* Try for the specified number of milliseconds for the BSY bit to clear or
* IDE interrupt assertion. //申请特定毫秒的等待使bsy 清0,或者 ide 中断声明
*/
int awaitBSYZeroOrINTRQ(int iMS)
{
int ret_code = -1; /* Assume failure until proven otherwise */
unsigned int uiStartTime; //起始时间
volatile unsigned int uiDeltaTime; //
uiStartTime = getTime(); //获得一个节拍起始时间??
do
{
if(!(IORD_ALTERA_AVALON_CF_IDE_ALTERNATE_STATUS(ide_base) & AltStatusRegBitBSY))//读状态寄存器,bsy为0返回0
{
ret_code = 0;
break;
}
if(IDEinterrupt == 1)
{
IDEinterrupt = 0;
ret_code = 0;
break;
}
uiDeltaTime = getTime() - uiStartTime;
} while(uiDeltaTime < iMS);
return ret_code;
}
/*
* awaitDRQ()// 等待drq 申请一个特定的时间 等待drq位设定
*
* Try for the specified number of milliseconds for the DRQ bit to set.
*/
int awaitDRQ(int iMS)
{
int ret_code = -1; /* Assume failure until proven otherwise */
volatile unsigned int uiStartTime, uiDeltaTime;
unsigned short usStatus;
uiStartTime = getTime();
//年前工作总结 完成了成了cf卡的读写
while((uiDeltaTime = getTime() - uiStartTime) < iMS)
{
usStatus = IORD_ALTERA_AVALON_CF_IDE_ALTERNATE_STATUS(ide_base);//读状态寄存器
if(usStatus & AltStatusRegBitDRQ) //如果状态寄存器的drq位为1 返回 0
{
ret_code = 0;
break;
}
}
if(ret_code) //如果返回1
{
printf("awaitDRQ; error: timeout awaiting DRQ=1\n"); //说明超时
printf("error register: 0x%X\n", IORD_ALTERA_AVALON_CF_IDE_ERROR(ide_base));
}
else
{
#if IDE_DEBUG
printf("awaitDRQ: DRQ found after %d ms\n", uiDeltaTime);
#endif
}
return ret_code;
}
/*
* awaitINTRQ()
*
* Try for the specified number of milliseconds for IDE interrupt assertion.//申请一个特定的时间声明ide中断
*/
int awaitINTRQ(int iMS)
{
int ret_code = -1; /* Assume failure until proven otherwise */
volatile unsigned int uiStartTime, uiDeltaTime;
uiStartTime = getTime();
while((uiDeltaTime = getTime() - uiStartTime) < iMS)
{
if (IDEinterrupt == 1)
{
IDEinterrupt = 0;
ret_code = 0;
break;
}
}
if(ret_code)
{
printf("awaitINTRQ: error: timeout awaiting INTRQ=1\n");
printf("error register: 0x%X\n", IORD_ALTERA_AVALON_CF_IDE_ERROR(ide_base));
}
else
{
#if IDE_DEBUG
printf("awaitINTRQ: INTRQ found after %d ms\n", uiDeltaTime);
#endif
}
return ret_code;
}
/*
* awaitBSYZero() // 等待bsy位置0
*
* Try for the specified number of milliseconds for the BSY bit to clear.
*/
int awaitBSYZero(unsigned int uiTimeout)
{
int ret_code = -1; /* Assume failure until proven otherwise */
unsigned int uiStartTime;
volatile unsigned int uiDeltaTime;
uiStartTime = getTime();
do
{
if(!(IORD_ALTERA_AVALON_CF_IDE_ALTERNATE_STATUS(ide_base) & AltStatusRegBitBSY))
{
ret_code = 0;
break;
}
uiDeltaTime = getTime() - uiStartTime;
} while(uiDeltaTime < uiTimeout);
return ret_code;
}
/*
* awaitBSYOne() //等待bsy位置1
*
* Try for the specified number of milliseconds for the BSY bit to set.
*/
int awaitBSYOne(unsigned int uiTimeout)
{
int ret_code = -1; /* Assume failure until proven otherwise */
volatile unsigned int uiStartTime, uiDeltaTime;
uiStartTime = getTime();
while ((uiDeltaTime = getTime() - uiStartTime) < uiTimeout)
{
if(IORD_ALTERA_AVALON_CF_IDE_ALTERNATE_STATUS(ide_base) & AltStatusRegBitBSY)
{
ret_code = 0;
break;
}
}
return ret_code;
}
/*
* awaitBSYZeroDRDYOne() //等待10毫秒时间使bsy清0,drdy位置1
*
* Try 10 milliseconds for the BSY bit to clear and DRDY bit to set.
*/
int awaitBSYZeroDRDYOne(void)
{
int ret_code = -1; /* Assume failure until proven otherwise */
unsigned short r;
volatile unsigned int uiStartTime, uiDeltaTime;
uiStartTime = getTime();
while ((uiDeltaTime = getTime() - uiStartTime) < 10)
{
r = IORD_ALTERA_AVALON_CF_IDE_ALTERNATE_STATUS(ide_base);
if ((r & (AltStatusRegBitBSY | AltStatusRegBitDRDY)) ==
AltStatusRegBitDRDY)
{
ret_code = 0;
break;
}
}
return ret_code;
}
/*
* PIODataInOrOutPreamble() //数据输入输出导言
*
* Ensure that the selected device is ready for operation.//确保选择的设备准备好操作
*
* This routine accomplishes steps (a) through (c) of PIO mode reads/writes.//这个程序完成读写的a到c步
*/
int PIODataInOrOutPreamble(int iDevice) //数据输入输出导言
{
/* Select the device to identify. */
if (iDevice > 1) //选择设备
{
printf("PIODataInOrOutPreamble: error: invalid device number(%d)\n",
iDevice);
return -1;
}
/* PIO read/write step (a) */
if (awaitBSYZero(1000))
{
printf("PIODataInOrOutPreamble: error: timeout (1) awaiting BSY=0\n");
return -1;
}
/* PIO read/write step (b) */ //设备/磁头寄存器写操作
IOWR_ALTERA_AVALON_CF_IDE_DEVICE_HEAD(ide_base, iDevice ? DevHeadRegBitDEV:0);
/* PIO read/write step (c) */
if (awaitBSYZeroDRDYOne())
{
printf("PIODataInOrOutPreamble: error: timeout awaiting BSY=0, DRDY=1\n");
return -1;
}
return 0;
}
/*
* Brief primer on PIO mode IDE reads. The comments below are referenced
* in relevant code in the low-level read routines:
*
* PIO Data In:
* a) The host reads the status or alt status reg until BSY=0.
* b) The host writes the dev/head register with the appropriate dev
* bit value.
* c) The host reads the status or alt status register until BSY=0 and
* DRDY=1.
* d) The host writes any required command parameters to the Features,
* Sector Count, Sector Number, Cylinder High, Cylinder Low and
* Device/Head registers.
* e) The host writes the command code to the Command register.
* f) The device sets the BSY bit and prepares to execute the command
* including preparation to transfer the first block of data to the
* host. (Note: it may take up to 400ns for BSY to go high.) //设备置bsy位准备执行命令包括准备传输第一数据块到主机 需要花费400ns使bsy置高
* g) When the block of data is available, the device sets the DRQ bit //当数据块是可用的,设备置drq位,如果错误状态存在的话,置drq位是可选的
* (setting the DRQ bit is optional if an error condition exists).
* If there is an error condition, the device sets the appropriate status//如果在错误情况下,设备设置适当地状态,在这种错误状态下,错误位被需求
* and error bits as required by that error condition. Finally, the device//最终,设备清除bsy位 并且声明中断。注意 ,需要时间当bsy设置和清除时
* clears BSY and then asserts INTRQ. (Note: there may be times when BSY //太快的的话主机可能不能够探测到bsy位被设置
* is set in f) and then cleared in g) so quickly that the host may not
* be able to detect that BSY had been set.)
* h) After detecting either BSY=0 (alt status) or INTRQ, the host reads and//探测到bsy位或者中断时,主机读并且保存状态寄存器
* saves the contents of the status register.
* i) If DRQ=1, the host transfers a block of data by reading the Data register.//如果drq=1,主机传输数据块通过读数据寄存器,
* If any error conditions are present in the status read in step h), the //如果任何错误状态存在,数据传输可能无效
* data transfer may not be valid.
* j) When the status register is read, the device negates INTRQ. In response to //当状态寄存器读的时候,设备否定(清除)中断,以适应完整的数据被读取
* the complete data block being read, one of the following actions is taken: //以下的动作可能发生:
* - if no error status was presented to the host in step h), and if transfer //如果错误状态在h步骤存在时,并且传输另一数据块是必须的
* of another block is required, the device sets BSY and the above sequence // 设备置bsy并且以上的次序重复开始从g步骤
* is repeated starting from step g).
* - If an error status was present in the status read in step h), the device //如果一个错误装态存在,读状态寄存器在h步骤的时候,设备清除drq并且命令执行完成
* clears DRQ and the command execution is complete.
* - If the last block was transfered, the device clears DRQ and the command //如果最后数据块被传输了,设备清drq命令执行完成,
* execution is complete.
*/
/*
* readSectorsCHSResult()
*
* Steps (f) through (j) of PIO mode read from IDE. Common to both CHS and LBA
* mode reads.
*/
//********************************************************************************//
//好好看明白这个函数的意思!!!!!
//*********************************************************************************//
int readSectorsGuts(int iSectorCount, unsigned short *pusBuffer) // guts 内容:最重要的组成部份或内部的零件:
{
unsigned short usStatus;
int iSect;
int i, iIndex;
/* PIO read steps (f) & (g) */
for (iSect = 0; iSect < iSectorCount; ++iSect) //最外侧循环:扇区数
{
if (awaitDRQ(1000))
{
printf("readSectorsGuts(): error: timeout awaiting DRQ\n");
}
if (awaitBSYZero(1000))
{
printf("readSectorsGuts(): error: timeout (2) awaiting BSY=0\n");
return -1;
}
if (awaitINTRQ(5000))
{
printf("readSectorsGuts(): error: timeout awaiting INTRQ=1\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -