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

📄 pci.all

📁 在dos下读写pci卡
💻 ALL
📖 第 1 页 / 共 3 页
字号:
/*
   '**********************************************************************
   '*  Program  : CNTINT.C                                               *
   '*  Revision : 1.00                                                   *
   '*  Date     : 06/25/2002                      Arbor dvantech Corp.   *
   '*====================================================================*
   '*                                                                    *
   '*  pDAQ-722 has 2 16-bit Timer supporting this feature.              *
   '*  They generate INTERRUPT if reaching the terminal count.           *
   '*                                                                    *
   '*  This demo program performs Counter Interrupt by using Counter 2.  *
   '*  It will generate interrupt after 100 event counts.                *
   '*                                                                    *
   '**********************************************************************
*/
#include <dos.h>
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include "PCI.C"
#include "pDAQ722.h"

/************
 * Global variable declare
 ************/
dword gdwBaseAddr;         //CS0 Base address
dword gdwBaseAddrCs1;      //CS1 Base address
dword gdwBaseAddrBa1;      //Local contrl Base address
int   giIrqNum;            //IRQ number
int   giIntControlRegAddr; //pDAQ-722 Interrupt control ragister address.
int   giIrqFlagBit;        //Interrupt flag
long  glIntCount;          //Interrupt generate count

/***********
 * Local fucntion declare
 ***********/
void interrupt IrqHandler(void);
byte InitInterrupt( int iIrqNum,
                    void interrupt (*pIsrHandler)(),
                    void interrupt (**pOldIsr)() );
void RestoreOldIsr(int iIrqNum, byte ucIrqMask, void interrupt (*pOldIsr)() );

void main(void)
{
  word  wVendorId, wDeviceId, wIndex;
  int   iErrCode;
  byte  ucBusNumber, ucDevAndFunc;
  dword dwData,dwINTCSR;

  int   iPort, iPortAddr, iCfgAddr;
  byte  ucCfgReg, ucDiCfgWord, ucTrigType;

  word wCount;

  void interrupt (*pOldIsr)(void);
  byte  ucIrqMask;
  long  lPreIntCount;

  wVendorId = VENDOR_ID;
  wDeviceId = DEVICE_ID;
  wIndex = 0;

  clrscr();
  printf("Arbor Technology Corp.\n\n");
  printf("Counter Interrupt demo program.\n");
  printf("Signals connection:\n");
  printf("  Channel 1 Clock : TCLK_B1(pin 16) and TCLK_A1(pin 34)\n");
  printf("  Channel 1 GATE  : TGT_B1(pin 17) and TGT_A1(pin 35)\n");
  printf("  Channel 2 Clock : TCLK_B2(pin 18) and TCLK_A2(pin 36)\n");
  printf("  Channel 2 GATE  : TGT_B2(pin 19) and TGT_A2(pin 37)\n");

  //Get IRQ source, Counter channel 1 or 2
  do
  {
    printf("\nChoose interrupt source: 1=Counter1, 2=Counter2 ");
    iPort=getche();
  }while(iPort < 0x31 || iPort > 0x32);

  iPort = iPort & 0x0f;        //Select counter Port
  wCount = 100;                //Down count value
  clrscr();

  printf("This program generate interrupt every while the counter %d", iPort);
  printf(" gets %d events.", wCount);
  printf("\n\nPress any key to start this function...");
  getch();

 /***************************
  * Get pDAQ-72x's resource
  ***************************/
  //
  // Search pDAQ-72x
  //
  for( wIndex=0; wIndex < 32; wIndex++)
  {
    iErrCode = find_pci_device(
                  wDeviceId,
                  wVendorId,
                  wIndex,
                  &ucBusNumber,
                  &ucDevAndFunc );
    if (iErrCode == NOT_SUCCESSFUL )
    {
       printf("\n pDAQ-720/722 search fail.\n");
       exit(1);
    }
    iErrCode = read_configuration_dword(
                  ucBusNumber,
                  ucDevAndFunc,
                  PCI_CS_SUBSYSTEM_ID,
                  &dwData);
    if(dwData == SUBSYSTEM_ID)
      break;
  }

  //
  //Get base address, from PCI base address range 2
  //
  iErrCode = read_configuration_dword(
                ucBusNumber,
                ucDevAndFunc,
                PCI_CS_BASE_ADDRESS_2,
                &dwData);
  if (iErrCode == NOT_SUCCESSFUL)
  {
    printf("\npDAQ-72x gets base address failure.\n");
    exit(1);
  }
  else
    gdwBaseAddr = dwData & 0xfffffffc;

  //
  //Get base address, from PCI base address range 3
  //
  iErrCode = read_configuration_dword(
                ucBusNumber,
                ucDevAndFunc,
                PCI_CS_BASE_ADDRESS_3,
                &dwData);
  if (iErrCode == NOT_SUCCESSFUL)
  {
    printf("\npDAQ-722 gets base address fail.\n");
    exit(1);
  }
  else
    gdwBaseAddrCs1 = dwData & 0xfffffffc;

  //
  //Get base address, from PCI base address range 1
  //
  iErrCode = read_configuration_dword(
                ucBusNumber,
                ucDevAndFunc,
                PCI_CS_BASE_ADDRESS_1,
                &dwData);
  if (iErrCode == NOT_SUCCESSFUL)
   {
      printf("\npDAQ-722 gets base address fail.\n");
      exit(1);
   }
   else
      gdwBaseAddrBa1 = dwData & 0xfffffffc;

  /***************************
   * Device configuration
   ***************************/
  //Interrupt source selection
  outportb(gdwBaseAddr+0x0c, 0x03);

  //Clear Interrupt
  outportb(gdwBaseAddrCs1, 0x00);

  //
  // enable PLX 9050 PCI interrupt
  //
  dwINTCSR = inportb(gdwBaseAddrBa1+0x4c);
  dwData = dwINTCSR;
  if(iPort == 1)
    dwData = dwData | 0x01;    //Local Interrupt 1 Enable
  else
    dwData = dwData | 0x08;    //Local Interrupt 2 Enable

  outportb(gdwBaseAddrBa1+0x4c, dwData);

  //
  // Get Interrupt line
  //
  iErrCode = read_configuration_dword(
                ucBusNumber,
                ucDevAndFunc,
                PCI_CS_INTERRUPT_LINE,
                &dwData);
  if (iErrCode == NOT_SUCCESSFUL)
  {
    printf("\npDAQ-722 gets interrupt line fail.\n");
    exit(1);
  }
  else
    giIrqNum = dwData & 0xf;

 /**************
  * Install ISR.
  **************/
  ucIrqMask = InitInterrupt(giIrqNum, IrqHandler, &pOldIsr);

 /*************************************
  * Program counter to Mode 4 for generating interrupt cyclically.
  *
  * Base + 27, control register, standard mode
  * bit#  7   6   5   4   3   2   1   0
  * value SC1 SC2 RW1 RW0 M2  M1  M0  BCD
  *
  *   SC1 SC0 Select Counter     |  RW1 RW2 Select R/W operation
  *    0   0           0         |   0   0  Counter latch
  *    0   1           1         |   0   1  Read/write LSB
  *    1   0           2         |   1   0  Read/write MSB
  *    1   1  Read-back comand   |   1   1  R/W LSB first then MSB
  *
  *   M2 M1 M0 Mode
  *   0  0  0  0  Stop on terminal count
  *   0  0  1  1  Programable one shot
  *   0  1  0  2  Rate generate
  *   0  1  1  3  Square wave generator
  *   1  0  0  4  Software triggered strobe
  *   1  0  1  5  Hardware triggered strobe
  ******************************/
  iPortAddr = iPort + 8;      //Counter's adress
  iCfgAddr = 0x0b;            //Counter configuration address

  //Write counter configuration word
  ucCfgReg = iPort << 6;       //Select counter port
  ucCfgReg = ucCfgReg | 0x30;  //R/W LSB first, then MSB
  ucCfgReg = ucCfgReg | 0x04;  //Mode 2, Rate generate
  ucCfgReg = ucCfgReg | 0;     //Binary counting
  outportb(gdwBaseAddr+iCfgAddr, ucCfgReg); //Write down control word

  //Write down counting value
  outportb(gdwBaseAddr+iPortAddr, wCount & 0xff);         //Write LSB
  outportb(gdwBaseAddr+iPortAddr, (wCount >> 8 ) & 0xff); //Write MSB



  /*************************************
   * Config to Counter interrupt mode
   * port#           Port C1       |   Port C0
   * bit #         D7  D6  D5  D4  | D3  D2  D1  D0
   * Abbreviation  F1  E1  M11 M10 | F0  E0  M01 M00
   *
   *  Mx1 Mx0  Port_GRP_x              | Ex   Triggering edge
   *   0   0   Disable interrupt       |  0   Rising edge trigger
   *   0   1   Source=PCx0             |  1   Falling edge trigger
   *   1   0   Source=PCx0 && PCx4     |
   *   1   1   Counter                 | Fx   Interrupt flag
   *
   *************************************/
   giIntControlRegAddr = 32;     //Interrupt Control Register address
   ucCfgReg = inportb(gdwBaseAddr+giIntControlRegAddr);

   switch(iPort)
   {
   case 1:    //Timer 1
      ucCfgReg = ucCfgReg & 0xf0; //Preserve not change bits
      ucCfgReg = ucCfgReg | 0x3;  //Source from Counter
      ucTrigType = 0x4;           //rising edge
      giIrqFlagBit = 0x8;         //Interrupt flag bit (F0)
      break;

   case 2:     //Counter 2
      ucCfgReg = ucCfgReg & 0xf;  //Preserve not change bits
      ucCfgReg = ucCfgReg | 0x30; //Source from counter
      ucTrigType = 0x40;          //rising edge
      giIrqFlagBit = 0x80;        //Interrupt flag bit (F1)
      break;

   default:
      printf("\nChannel %d not support Interrupt function.", iPort);
      printf("\nTerminate program!");
      exit(1);
   }

   outportb(gdwBaseAddr+giIntControlRegAddr, ucCfgReg);
   outportb(gdwBaseAddr+giIntControlRegAddr, ucCfgReg | ucTrigType);

   /************
    * Polling interrupt count
    ************/
   glIntCount = 0;
   lPreIntCount = -1;
   while(!kbhit())
   {
      if(lPreIntCount < glIntCount)
      {
         printf("\n\nInterrupt generated count: %lu", glIntCount);
         printf("\nPress any key to stop...");
         lPreIntCount = glIntCount;
      }
   }
   if(kbhit()) getch();
   /************
    * Restore interrupt Control/Status Register
    ************/
   outportb(gdwBaseAddrBa1+0x4c,dwINTCSR);

   /************
    * Stop device to generate interrupt
    ************/
   outportb(gdwBaseAddr+giIntControlRegAddr, 0);

   /************
    * Stop IRQ and restore system ISR
    ************/
   RestoreOldIsr(giIrqNum, ucIrqMask, pOldIsr);

}//main

/************************************************************************
 * Function:  Init ISR to handle device generated IRQ
 * Paramater: iIrqNum, IN, IRQ number.
 *            pIsrHandler,IN, ISR handler for installation.
 *            pOldIsr, OUT, Old ISR routine.
 * return:    IRQ mask
 ************************************************************************/
byte InitInterrupt( int iIrqNum,
                    void interrupt (*pIsrHandler)(),
                    void interrupt (**pOldIsr)() )
{
   byte ucIrqMask, ucTotalMask;

   //
   // 1. DISABLE PC INTERRUPT
   //
   disable();

   //
   // 2. STORE OLD INT. HANDLER */
   //
   if ( iIrqNum < 8 )
      *pOldIsr = getvect(iIrqNum+8);
   else
      *pOldIsr = getvect(iIrqNum-8+0x70);

   //
   // 3. SET INTERRUPT  VECTOR
   //
   if(iIrqNum < 8)
      setvect(iIrqNum+8, pIsrHandler);
   else
      setvect(iIrqNum-8+0x70, pIsrHandler);

   //
   // 4. ENABLE 8259 INT. MASK
   //
   if(iIrqNum < 8)
   {
      ucTotalMask = inportb(0x21);
      ucIrqMask = ucTotalMask & (0x01<<iIrqNum);
      outportb(0x21, ucTotalMask & ~(0x01<<iIrqNum) );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -