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

📄 pmdpci.c

📁 一个机器人的源代码.软件设计得超级好!是商业级代码.
💻 C
📖 第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////////////////////////////////
//
//  PMDpci.c -- parallel interface command/data transfer functions for the DK board 
//              using the PCI bus interface via the PLX MS Windows driver.
//
//  NOTE: This module is for reference only and cannot be compiled without the 
//        PLX source which can be purchased from PLX. (www.plxtech.com)
//        To use C-Motion with the PCI interface, link with the PMDPCI.obj file
//        and the PlxApi.lib file.
//
///////////////////////////////////////////////////////////////////////////////

#include <stdio.h>#ifdef _LINUX#include <sys/time.h>#else
#include <sys/timeb.h>
#endif#include <stdlib.h>

#include "PMDconio.h"
#include "PMDtypes.h"
#include "PMDocode.h"
#include "PMDecode.h"
#include "PMDtrans.h"
#include "PMDpci.h"
#include "PciTypes.h"
#include "PlxTypes.h"
#include "Plx.h"
#include "PciApi.h"
#include "PciRegs.h"

// only required if we are running in diagnostics mode
#include "PMDdiag.h"

/* local constants */
const int RDY_MASK = 0x8000;
const int INT_MASK = 0x4000;
const int ERR_MASK = 0x2000;

const int PCI_IOSPACE1_BASE = 0x8000;
const int PCI_IOSPACE0_BASE = 0x800;

// PCI SubDevice IDs
const int CARD_DK_ORIGINAL  = 0x9030;
const int CARD_DK_NAVIGATOR = 0x2811;
const int CARD_DK_MAGELLAN  = 0x2996;
const int CARD_MB_NAVIGATOR = 0x2746;
const int CARD_MB_MAGELLAN  = 0x2960;

static U32 g_IopSpaceBase   = 0;           // DPRAM offset
static IOP_SPACE g_IopSpace = IopSpace0;   // PCI IO space number
static int g_bHasDPRAM      = TRUE;


PMDuint16 PMDPCI_WaitUntilReady(void* transport_data);
PMDuint16 PMDPCI_HandleError(void* transport_data);

//*****************************************************************************
PMDuint16 PMDPCI_InitPort(PMDPCIIOTransportData* transport_data)
{
    RETURN_CODE rc;
    DEVICE_LOCATION device;
    U32 plxDeviceCount;
    U8 SdkMajor;
    U8 SdkMinor;
    U8 SdkRevision;
    U32 RegValue;
    int nDeviceID;
    int nBasePortAddress;
    int nResetPortAddress;

    device.BusNumber  = -1;
    device.SlotNumber = -1;
    device.DeviceId   = -1; 
    device.VendorId   = 0x10b5;  //PLX vendor id
    device.SerialNumber[0] = '\0';

    rc = PlxSdkVersion(
        &SdkMajor,
        &SdkMinor,
        &SdkRevision);

    //plxDeviceCount = FIND_AMOUNT_MATCHED;
    plxDeviceCount = transport_data->nBoardNo; // Card numbering starts at 0
    
    rc = PlxPciDeviceFind(&device, &plxDeviceCount);
  
    if ((rc == ApiInvalidDeviceInfo))
    {
        // only report a version conflict if the function fails
        if (SdkMajor != 3 || SdkMinor != 5)
        {
            PMDprintf("Incorrect PLX SDK version. Expecting version 3.5 got %d.%d\n", (int)SdkMajor, (int)SdkMinor );
    		return PMD_ERR_OpeningWindowsDriver;
        }
    }

    if ((rc != ApiSuccess))// || (plxDeviceCount == 0))
    {
        PMDprintf("Error in scanning for devices:\n");
        PMDprintf("No supported device found\n");
		return PMD_ERR_OpeningWindowsDriver;
    }

    /* Open the device */
    rc = PlxPciDeviceOpen (&device, &transport_data->hDrv);
    if (rc != ApiSuccess)
    {
        PMDprintf("Errors in opening device.\n");
        PMDprintf("Returned code is %d\n",rc);
		return PMD_ERR_OpeningWindowsDriver;
    }

	if( transport_data->hDrv == INVALID_HANDLE_VALUE )
	{
#ifndef _LINUX		int err = GetLastError();                PMDkbhit( "Attempt to open driver returned error %ld\n", err );#else		PMDprintf( "Attempt to open driver returned error %ld\n",INVALID_HANDLE_VALUE);                PMDkbhit();#endif		
		return PMD_ERR_OpeningWindowsDriver;
	}

    // get PCI SubsystemID
    RegValue = PlxPciConfigRegisterRead(device.BusNumber, device.SlotNumber, CFG_SUB_VENDOR_ID, &rc);
    nDeviceID = 0;
    nBasePortAddress = 0;

    if (rc == ApiSuccess)
        nDeviceID = RegValue>>16;
    else
		return PMD_ERR_OpeningWindowsDriver;

    // get io port addresses for Motion Board and PMD DK rev D boards
    if (nDeviceID != CARD_DK_ORIGINAL)
    {
		if (nDeviceID == CARD_DK_NAVIGATOR
        ||  nDeviceID == CARD_DK_MAGELLAN)
        {
            RegValue = PlxPciConfigRegisterRead(device.BusNumber, device.SlotNumber, CFG_BAR3, &rc);
        }
        else if (nDeviceID == CARD_MB_NAVIGATOR
             ||  nDeviceID == CARD_MB_MAGELLAN)
        {
            RegValue = PlxPciConfigRegisterRead(device.BusNumber, device.SlotNumber, CFG_BAR3, &rc);
            if (rc == ApiSuccess)
                nResetPortAddress = RegValue - 1; // port for complete hard reset including FPGA
            RegValue = PlxPciConfigRegisterRead(device.BusNumber, device.SlotNumber, CFG_BAR2, &rc);
        }
        else
        {
    	    PMDprintf( "No suppported PCI card found. SubVendorID: %d\n", nDeviceID );
		    return PMD_ERR_OpeningWindowsDriver;
        }
        if (rc == ApiSuccess)
            nBasePortAddress = RegValue - 1;	        if (nBasePortAddress <= 0)
        {
    	    PMDprintf( "Invalid PCI port address: %d\n", nBasePortAddress );
		    return PMD_ERR_OpeningWindowsDriver;
        }
    }

	// set IO space values dependant on card type
    if (nDeviceID == CARD_MB_MAGELLAN)
		g_IopSpace = IopSpace2; // DPRAM on the Magellan Motion Board is located at memory space 2

    if (nDeviceID == CARD_MB_NAVIGATOR)
		g_bHasDPRAM = FALSE;    // no DPRAM on the Navigator Motion Board

	/* disabled this setting because the offset is required in SetBufferStart anyway
    if (nDeviceID == CARD_DK_NAVIGATOR
    ||  nDeviceID == CARD_MB_NAVIGATOR
    ||  nDeviceID == CARD_DK_ORIGINAL)
		g_IopSpaceBase = PCI_IOSPACE0_BASE; // Navigator reserves the first 0x800 bytes
	*/
    transport_data->nDeviceID = nDeviceID;
    transport_data->nBasePortAddress = nBasePortAddress;
	return PMD_NOERROR;
}

//*****************************************************************************
void PMDPCI_Close(void* transport_data)
{
	PMDPCIIOTransportData* PIOtransport_data = (PMDPCIIOTransportData*)transport_data;

	if ( PIOtransport_data->hDrv!=INVALID_HANDLE_VALUE )
	{
		PlxPciDeviceClose( PIOtransport_data->hDrv );
		PIOtransport_data->hDrv = INVALID_HANDLE_VALUE;
	}
    free(transport_data);
}



/******************************************************************************
 *
 * Function Name: WriteCMD()
 *
 ******************************************************************************/
PMDuint16 PMDPCI_WriteCMD(void* transport_data, PMDuint16 command)
{
	PMDPCIIOTransportData* PIOtransport_data = (PMDPCIIOTransportData*)transport_data;
    RETURN_CODE rc;
	U32 temp=command;

	PMDPCI_WaitUntilReady(transport_data);
   //	PMDprintf("In WriteCMD\n");  //      while(!PMDkbhit());
    if (PIOtransport_data->nDeviceID == CARD_DK_ORIGINAL)
    {
    	// Start copying data at IOP address localStartOffset
	    rc = PlxBusIopWrite(PIOtransport_data->hDrv, 
						IopSpace1, 
						PCI_IOSPACE1_BASE + 2,
						TRUE,
						&temp, 
						2, 
						BitSize16);
    }
    else
    {
    	rc = PlxIoPortWrite(PIOtransport_data->hDrv, 
						PIOtransport_data->nBasePortAddress + 2,
						BitSize16,
						&temp); 
    }

	if (rc != ApiSuccess)
		return PMD_ERR_Driver;

    return PMD_NOERROR;
} /* end WriteCMD */

/******************************************************************************
 *
 * Function Name: WriteData()
 *
 ******************************************************************************/
PMDuint16 PMDPCI_WriteData(void* transport_data, PMDuint16 data)
{
	PMDPCIIOTransportData* PIOtransport_data = (PMDPCIIOTransportData*)transport_data;
    RETURN_CODE rc;
	U32 temp=data;

	PMDPCI_WaitUntilReady(transport_data);
    
    if (PIOtransport_data->nDeviceID == CARD_DK_ORIGINAL)
    {
    	// Start copying data at IOP address localStartOffset
	    rc = PlxBusIopWrite(PIOtransport_data->hDrv, 
						IopSpace1, 
						PCI_IOSPACE1_BASE,
						TRUE,
						&temp, 
						2, 
						BitSize16);
    }
    else
    {
    	rc = PlxIoPortWrite(PIOtransport_data->hDrv, 
						PIOtransport_data->nBasePortAddress,
						BitSize16,
						&temp); 
    }

	if (rc != ApiSuccess)
		return PMD_ERR_Driver;

    return PMD_NOERROR;
} /* end WriteData */

/******************************************************************************
 *
 * Function Name: ReadData()
 *
 ******************************************************************************/
PMDuint16 PMDPCI_ReadData(void* transport_data, PMDuint16* data)
{
	PMDPCIIOTransportData* PIOtransport_data = (PMDPCIIOTransportData*)transport_data;
    RETURN_CODE rc;

	U32 temp = 0;

	PMDPCI_WaitUntilReady(transport_data);

    if (PIOtransport_data->nDeviceID == CARD_DK_ORIGINAL)
    {
	    // Now read back the data from IOP address localStartOffset
	    rc = PlxBusIopRead(PIOtransport_data->hDrv, 
						IopSpace1, 
						PCI_IOSPACE1_BASE,
						TRUE,
						&temp, 
						2, 
						BitSize16);
    }
    else
    {
    	rc = PlxIoPortRead(PIOtransport_data->hDrv, 
						PIOtransport_data->nBasePortAddress,
						BitSize16,
						&temp); 
    }

	if (rc != ApiSuccess)
		return PMD_ERR_Driver;

	*data = (PMDuint16)temp;

    return PMD_NOERROR;
} /* end ReadData */

/******************************************************************************
 *
 * Function Name: ReadStatus()
 *
 ******************************************************************************/
PMDuint16 PMDPCI_ReadStatus(void* transport_data, PMDuint16* status)
{
	PMDPCIIOTransportData* PIOtransport_data = (PMDPCIIOTransportData*)transport_data;
    RETURN_CODE rc;
    U32 temp;

    if (PIOtransport_data->nDeviceID == CARD_DK_ORIGINAL)
    {
	    // Now read back the data from IOP address localStartOffset
	    rc = PlxBusIopRead(PIOtransport_data->hDrv, 
						IopSpace1, 
						PCI_IOSPACE1_BASE + 2,
						TRUE,
						&temp, 
						2, 
						BitSize16);
    }
    else
    {
    	rc = PlxIoPortRead(PIOtransport_data->hDrv, 
						PIOtransport_data->nBasePortAddress + 2,
						BitSize16,
						&temp); 
    }

    if (rc != ApiSuccess)
		return PMD_ERR_Driver;

	*status = (PMDuint16)temp;

    return PMD_NOERROR;
} /* end ReadStatus */

/******************************************************************************
 *
 * Function Name: HardReset()
 *
 ******************************************************************************/
PMDuint16 PMDPCI_HardReset(void* transport_data)
{
	PMDPCIIOTransportData* PIOtransport_data = (PMDPCIIOTransportData*)transport_data;
    RETURN_CODE rc = ApiFailed;
    U32 temp = 0;

    if (PIOtransport_data->nDeviceID == CARD_DK_ORIGINAL)
    {
	    rc = PlxBusIopWrite(PIOtransport_data->hDrv, 
						IopSpace1, 
						PCI_IOSPACE1_BASE + 0x10,
						TRUE,
						&temp, 
						2, 
						BitSize16);
    }
    else if (PIOtransport_data->nDeviceID == CARD_DK_NAVIGATOR)

⌨️ 快捷键说明

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