⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cf卡.txt

📁 cf卡读写成功的例子
💻 TXT
📖 第 1 页 / 共 3 页
字号:

#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 + -