📄 pmdpci.c
字号:
///////////////////////////////////////////////////////////////////////////////
//
// 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 + -