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

📄 pcidio96_aux.c

📁 windows系统下实时代码,可以进行底层硬件的实时操作
💻 C
字号:
/*++
 *
 * Copyright (c) 1998-2005 Ardence, Inc. All rights reserved.
 *
 * Nodule Name:
 *
 *      PciDio96_Aux.c
 *
 * Abstract:
 *
 *      Auxilliary test program for testing interrupts from PCI-DIO-96 card.
 *      It has four modules: 
 *			PciDio96_Search, PciDio96_Init, PciDio96_Cleanup and PciDio96_Fail. 
 *		Refer to User's Manual of PCI-DIO-96 for initialization procedures and 
 *			device parameters.
 *
 * Author:
 *
 *      Duncan Xue      
 *
 * Environment:
 *
 *      RTX application 
 *
 --*/


#include <windows.h>
#include <rtapi.h>
#include "pcidio96registeraddressmap.h"


//
// local variables
//
PCHAR vBAR0=NULL, vBAR1=NULL;   // pointer virtual memory addresses returned by RtMapMemory
PUCHAR _base_addr;				// defined in pcidio96registeraddressmap.h

//
// This routine searches for a PCI-DIO-96 card on the machine's PCI buses.
// It returns the bus number when the specified (by CardNumber) PCI-DIO-96 card has 
// been found, or returns -1 if no device found.
//               
int
PciDio96_Search(
				int CardNumber,					// input: PCI card to find
				PCI_SLOT_NUMBER *pSlotNumber,	// output: pointer to slot number
				PPCI_COMMON_CONFIG  PciData		// output: PCI card information
			   )
{  
    ULONG   DeviceNumber;      // logical slot number for the PCI adapter
    ULONG   FunctionNumber;    // function number on the specified adapter
    ULONG   BytesWritten;      // return value from RtGetBusDataByOffset
    ULONG   Bus;               // bus number
    BOOLEAN Flag = TRUE;       // TRUE as long as we have PCI busses           
	int CardIndex = 0;
    
    pSlotNumber->u.bits.Reserved = 0; 


    // 
    // All PCI cards have been searched when we are out of PCI busses. (Flag = 0) 
    //
    for (Bus=0; Flag; Bus++)
	{ 
         for (DeviceNumber=0; DeviceNumber < PCI_MAX_DEVICES && Flag; DeviceNumber++)
		 { 
            pSlotNumber->u.bits.DeviceNumber = DeviceNumber; 
 
            for (FunctionNumber=0; FunctionNumber < PCI_MAX_FUNCTION; FunctionNumber++)
			{ 
                pSlotNumber->u.bits.FunctionNumber = FunctionNumber; 
 
                BytesWritten = RtGetBusDataByOffset (
                    PCIConfiguration, 
                    Bus, 
                    pSlotNumber->u.AsULONG, 
                    PciData, 
                    0,
                    PCI_COMMON_HDR_LENGTH 
                    ); 
 
                if (BytesWritten == 0)
				{ 
                    // out of PCI buses 
                    Flag = FALSE; 
                    break; 
                } 
 
                if (BytesWritten == 2 && PciData->VendorID == PCI_INVALID_VENDORID)
				{ 
                    // no device at this slot number, skip to next slot 
                    break; 
                } 

                //
                // A device is found, if this is our card (National Instruments PCI-DIO-96)
				//  return, otherwise continue until all buses have been searched.
                // 
                if ((PciData->VendorID == 0x1093) && (PciData->DeviceID == 0x0160))
                    if(++CardIndex == CardNumber) // This is our card!!
						return Bus;   // stop searching                                                                                    

            } // FunctionNumber-loop

		 } // DeviceNumber-loop

    }  // Bus-loop

	return -1;   
}



//
// This routine initializes the PCI-DIO-96 card found on the machine's PCI bus.
// It returns virtual base address of the board registers when succeeds 
// or NULL otherwise
//               
PCHAR
PciDio96_Init(
				int intBusNumber,				// input: interrupt bus number
				PCI_SLOT_NUMBER *pSlotNumber,	// input: pointer to slot number
				PPCI_COMMON_CONFIG  PciData		// input: PCI card information
			 )
{
    LARGE_INTEGER BAR0;             // base port address of the MITE
    LARGE_INTEGER BAR1;             // base port address of the board registers
    LARGE_INTEGER tBAR0, tBAR1;     // translated base addresses returned by RtMapMemory
    ULONG AddressSpace = 0;         // indicates memory space
    ULONG window_data_value = 0; 

	//
    // Put the BusAddresses into other variables
	//
    BAR0.QuadPart = PciData->u.type0.BaseAddresses[0];  // MITE address         
    BAR1.QuadPart = PciData->u.type0.BaseAddresses[1];  // new board address   

    //
    // Translate the base port addresses to system mapped addresses. 
    //
    if (!RtTranslateBusAddress( 
        PCIBus, 
        intBusNumber, 
        BAR0,
        &AddressSpace, 
        &tBAR0
        ))
	{
		RtPrintf("tBAR0: RtTranslateBusAddress failed.\n");
		return NULL;
	}
   
    
    if (!RtTranslateBusAddress( 
        PCIBus, 
        intBusNumber, 
        BAR1,
        &AddressSpace, 
        &tBAR1
        )) 
	{
        RtPrintf("tBAR1: RtTranslateBusAddress failed.\n");
		return NULL;
	}


    //
    // Map the addresses to virtual addresses the software can use
    //
    vBAR0=RtMapMemory( tBAR0, 4*1024, 0); // 4K, cache disabled
    if (vBAR0 == NULL)
	{
        RtPrintf("BAR0: Failure on RtMapMemory.\n");
		return NULL;
	}

               
    vBAR1=RtMapMemory( tBAR1, 4*1024, 0); // 4K, cache disabled
    if (vBAR1 == NULL)
	{
        RtPrintf("BAR1: Failure on RtMapMemory.");
		return NULL;
    }

	_base_addr = vBAR1;  // no mapping

    //
    // Set the command parameter so we can access the PCI device's control registers.
    // 
    PciData->Command = (PCI_ENABLE_IO_SPACE | PCI_ENABLE_MEMORY_SPACE |
						PCI_ENABLE_BUS_MASTER | PCI_ENABLE_WRITE_AND_INVALIDATE);
    RtSetBusDataByOffset(
        PCIConfiguration,
        intBusNumber,
        pSlotNumber->u.AsULONG,
        PciData,
        0,
        PCI_COMMON_HDR_LENGTH
        );

	   Sleep(500);


    //
    // Configure PCI MITE ASIC
    // No 1 MB limit - no need to remap the memory.
    // Note: You need to use the BusRelativeAddress to set the window_data_value. 
    //
    window_data_value = ( (0xffffff00 & (ULONG)BAR1.LowPart) | (0x00000080) );
    PTL(vBAR0+0x000000c0) = window_data_value;
	
	return _base_addr;
}


//
// cleanup interrupt vector and mapped memory  
//
void PciDio96_Cleanup(
					  HANDLE aHandle,  // handle of interrupt from RtAttachInterruptVector call
					  int cleanMode	   // clean mode: 1 or 2, relevant only when aHandle not NULL
									   // If 1 the test does normal cleanup before exiting
									   // If 2 the test will use RtPrintf and sleep to allow tester to
									   // use Windows NT Diagnostict to verify resource use
					  )
{
	BOOL Result;

	if(aHandle != NULL)
	{
        if (cleanMode == 2)
        {
            RtPrintf("30 sec to verify interrupt resources still is claimed\n");
            Sleep(30000);
        }

		Result = RtReleaseInterruptVector(aHandle);

		if (cleanMode == 2)
        {
            RtPrintf("30 sec to verify interrupt resources is freed\n");
            Sleep(30000);
        }

		//
		// no need to enable interrupts here
		//

		if(!Result)
			PciDio96_Fail("Could not release interrupt for this card");
	}

	if(vBAR0 != NULL )
	{
		RtUnmapMemory(vBAR0);
		vBAR0 = NULL;
	}

	if(vBAR1 != NULL )
	{
		RtUnmapMemory(vBAR1);
		vBAR1 = NULL;
	}

}



/* fail: Utility routine: output error message and terminate the program 
 * with exit code 1.
 */
void PciDio96_Fail(char *mesg)
{
    RtPrintf("Fatal Error: %s (0x%X)\n", mesg, RtGetLastError());
    RtExitProcess(1);
}

⌨️ 快捷键说明

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