📄 pmdpci.c
字号:
{
rc = PlxIoPortWrite(PIOtransport_data->hDrv,
PIOtransport_data->nBasePortAddress + 0x18,
BitSize16,
&temp);
}
else //if (PIOtransport_data->nDeviceID == CARD_MB_NAVIGATOR)
{
rc = PlxIoPortWrite(PIOtransport_data->hDrv,
PIOtransport_data->nBasePortAddress + 0x0E,
BitSize16,
&temp);
}
if (rc != ApiSuccess)
return PMD_ERR_Driver;
return PMD_NOERROR;
}
//*****************************************************************************
PMDuint16 PMDPCI_WaitUntilReady(void* transport_data)
{
#ifdef _LINUX S32 stopTime, currentTime; struct timeval now;#else DWORD stopTime, currentTime;#endif
PMDuint16 status=0;
#ifdef _LINUX gettimeofday(&now,NULL); stopTime = now.tv_sec * 1000l + now.tv_usec/1000l+1000;#else // GetTickCount returns time in ms
stopTime = GetTickCount() + 1000; // timeout is 1 sec
#endif
for(;;)
{
// poll ready port, if not ready, loop
PMDPCI_ReadStatus(transport_data, &status);
if (status&RDY_MASK)
return PMD_NOERROR;
#ifdef _LINUX gettimeofday(&now,NULL); currentTime = now.tv_sec * 1000l + now.tv_usec/1000l;#else
currentTime = GetTickCount();
#endif
if (currentTime > stopTime)
{
// check the ready again, even after a timeout
PMDPCI_ReadStatus(transport_data, &status);
if (status&RDY_MASK)
return PMD_NOERROR;
return PMD_ERR_CommTimeoutError;
}
}
} /* end WaitUntilReady */
//*****************************************************************************
PMDuint16 PMDPCI_Send(void* transport_data, PMDuint8 xCt, PMDuint16* xDat, PMDuint8 rCt, PMDuint16* rDat)
{
int index,i;
PMDuint16 cksum, status;
PMDuint16 calcSum;
PMDuint16 result = PMD_NOERROR;
PMDPCIIOTransportData* PIOtransport_data = (PMDPCIIOTransportData*)transport_data;
HANDLE hDrv = PIOtransport_data->hDrv;
if (hDrv == INVALID_HANDLE_VALUE)
return PMD_ERR_DK2000NotInitialized;
if ( PMDPCI_WriteCMD(transport_data, xDat[0]) )
return PMD_ERR_Driver;
// check for success/failure of this command
if ( PMDPCI_WaitUntilReady(transport_data) )
return PMD_ERR_CommTimeoutError;
// put the data into the DK2000
// one word at a time
for(index=1; index<xCt; index++)
{
if ( PMDPCI_WriteData(transport_data, xDat[index]) )
return PMD_ERR_Driver;
}
// get the data from the DK2000
for(index=0; index<rCt; index++)
{
if ( PMDPCI_ReadData(transport_data, &rDat[index]) )
return PMD_ERR_Driver;
}
if (PIOtransport_data->bVerifyChecksum)
{
if ( PMDPCI_ReadData(transport_data, &cksum) )
return PMD_ERR_Driver;
calcSum = 0;
for( i=0; i<xCt; i++ ) calcSum += xDat[i];
for( i=0; i<rCt; i++ ) calcSum += rDat[i];
if( calcSum != cksum )
{
PMDprintf( "Checksum error, sent: ");
for( i=0; i<xCt; i++ ) PMDprintf( " 0x%04hx", xDat[i] );
PMDprintf( "\n" );
if( rCt ) PMDprintf( " received:" );
for( i=0; i<rCt; i++ ) PMDprintf( " 0x%04hx", rDat[i] );
PMDprintf( "\nExpected: 0x%04hx, got: 0x%04hx\n", calcSum, cksum );
return PMD_ERR_ChecksumError;
}
}
if ( PMDPCI_ReadStatus(transport_data, &status) )
return PMD_ERR_Driver;
if (status & ERR_MASK)
{
if (PIOtransport_data->bDiagnostics)
{
result = PMDPCI_HandleError(transport_data);
PMDprintf("Command Error: %s\n", PMDGetErrorMessage(result));
}
return PMD_ERR_CommandError;
}
return result;
}
/******************************************************************************
*
* Function Name: ReadPCI_DPRAM()
*
******************************************************************************/
PMDuint16 PMDPCI_ReadDPRAM(void* transport_data, PMDuint32* data, PMDuint32 offset_in_dwords, PMDuint32 dwords_to_read)
{
PMDPCIIOTransportData* PIOtransport_data = (PMDPCIIOTransportData*)transport_data;
RETURN_CODE rc;
PMDuint32 i,swap;
if (g_bHasDPRAM == FALSE)
return PMD_ERR_Driver; // no DPRAM
rc = PlxBusIopRead(PIOtransport_data->hDrv,
g_IopSpace,
g_IopSpaceBase+(offset_in_dwords*4),
FALSE,
(PMDuint32*)data,
dwords_to_read*4,
BitSize32);
if (rc != ApiSuccess)
return PMD_ERR_Driver;
// the chip stores the double word in big endian word order
// so we need to word swap the results
for (i=0;i<dwords_to_read;i++)
{
swap = (data[i] & 0xffff) << 16;
data[i] = (data[i] >> 16) | swap;
}
return PMD_NOERROR;
} /* end ReadData */
/******************************************************************************
*
* Function Name: WritePCI_DPRAM()
*
******************************************************************************/
PMDuint16 PMDPCI_WriteDPRAM(void* transport_data, PMDuint32* data, PMDuint32 offset_in_dwords, PMDuint32 dwords_to_write)
{
PMDPCIIOTransportData* PIOtransport_data = (PMDPCIIOTransportData*)transport_data;
RETURN_CODE rc;
PMDuint32 i,swap;
if (g_bHasDPRAM == FALSE)
return PMD_ERR_Driver; // no DPRAM
// the chip stores the double word in big endian word order
// so we need to word swap the data before writing
for (i=0;i<dwords_to_write;i++)
{
swap = (data[i] & 0xffff) << 16;
data[i] = (data[i] >> 16) | swap ;
}
rc = PlxBusIopWrite(PIOtransport_data->hDrv,
g_IopSpace,
g_IopSpaceBase+(offset_in_dwords*4),
FALSE,
(PMDuint32*)data,
dwords_to_write*4,
BitSize32);
if (rc != ApiSuccess)
return PMD_ERR_Driver;
return PMD_NOERROR;
} /* end ReadData */
//*****************************************************************************
PMDuint16 PMDPCI_HandleError(void* transport_data)
{
PMDuint16 result;
PMDuint8 xCt;
PMDuint16 xDat[2];
PMDuint8 rCt;
PMDuint16 rDat[2];
static int GettingError = 0;
if (GettingError)
return PMD_ERR_CommunicationsError;
GettingError = 1;
xCt = 1;
xDat[0] = PMDOPGetHostIOError;
rCt = 1;
rDat[0] = PMD_NOERROR;
result = PMDPCI_Send(transport_data, xCt, xDat, rCt, rDat);
if (result == PMD_NOERROR)
{
result = rDat[0];
}
GettingError = 0;
return result;
}
//*****************************************************************************
PMDuint16 PMDPCI_GetStatus(void* transport_data)
{
PMDPCIIOTransportData* PIOtransport_data = (PMDPCIIOTransportData*)transport_data;
PMDuint16 status = 0;
PMDPCI_ReadStatus(PIOtransport_data, &status);
return status;
}
//*****************************************************************************
PMDuint16 PMDPCI_IsReady(void* transport_data)
{
PMDPCIIOTransportData* PIOtransport_data = (PMDPCIIOTransportData*)transport_data;
PMDuint16 status = 0;
PMDPCI_ReadStatus(PIOtransport_data, &status);
return (PMDuint16)(status&RDY_MASK?1:0);
}
//*****************************************************************************
PMDuint16 PMDPCI_HasInterrupt(void* transport_data)
{
PMDPCIIOTransportData* PIOtransport_data = (PMDPCIIOTransportData*)transport_data;
PMDuint16 status = 0;
PMDPCI_ReadStatus(PIOtransport_data, &status);
return (PMDuint16)(status&INT_MASK?1:0);
}
//*****************************************************************************
PMDuint16 PMDPCI_HasError(void* transport_data)
{
PMDPCIIOTransportData* PIOtransport_data = (PMDPCIIOTransportData*)transport_data;
PMDuint16 status = 0;
PMDPCI_ReadStatus(PIOtransport_data, &status);
return (PMDuint16)(status&ERR_MASK?1:0);
}
//*****************************************************************************
PMDuint16 PMDPCI_SetInterruptEvent(PMDAxisHandle* axis_handle, HANDLE *pEventHdl)
{
PMDPCIIOTransportData* PIOtransport_data = (PMDPCIIOTransportData*)axis_handle->transport_data;
PMDuint16 status = 0;
RETURN_CODE rc;
HANDLE hDevice = PIOtransport_data->hDrv;
PLX_INTR intrTypes;
memset(&intrTypes, 0, sizeof(PLX_INTR));
// intrTypes.PciINTApin = 1; this has no effect
intrTypes.IopToPciInt = 1;
#ifndef _LINUX rc = PlxIntrAttach(hDevice, intrTypes, pEventHdl);
#endif
// enable the "Local Interrupt 1 Enable" and "PCI Interrupt Enable" bits in the runtime register
// note: after the interrupt occurs the "Local Interrupt 1 Enable" bit is cleared
// see the PLX example code IntEvt.c for more info
intrTypes.PciMainInt = 1;
rc = PlxIntrEnable(hDevice, &intrTypes);
//rc = PlxIntrStatusGet(hDevice, &intrTypes); // for debugging
return (PMDuint16)(rc);
}
//*****************************************************************************
void PMDPCI_InitData(PMDPCIIOTransportData* transport_data)
{
// assign default values
memset(transport_data, 0, sizeof(PMDPCIIOTransportData));
transport_data->hDrv = INVALID_HANDLE_VALUE;
// by default always verify the checksum
transport_data->bVerifyChecksum = 1;
// by default enable diagnostics
transport_data->bDiagnostics = 0;
// by default set to first card found (numbering starts at 0)
transport_data->nBoardNo = 0;
transport_data->nBasePortAddress = 0;
transport_data->nDeviceID = 0;
}
//*****************************************************************************
PMDuint16 PMDPCI_Init(void* handle)
{
PMDAxisHandle* axis_handle = (PMDAxisHandle*) handle;
// setup function pointers
axis_handle->transport.SendCommand = PMDPCI_Send;
axis_handle->transport.GetStatus = PMDPCI_GetStatus;
axis_handle->transport.IsReady = PMDPCI_IsReady;
axis_handle->transport.HasInterrupt = PMDPCI_HasInterrupt;
axis_handle->transport.HasError = PMDPCI_HasError;
axis_handle->transport.HardReset = PMDPCI_HardReset;
axis_handle->transport.Close = PMDPCI_Close;
return PMDPCI_InitPort((PMDPCIIOTransportData*)axis_handle->transport_data);
}
//*****************************************************************************
PMDuint16 PMDSetupAxisInterface_PCI(PMDAxisHandle* axis_handle, PMDAxis axis_number, int board_number)
{
PMDPCIIOTransportData* transport_data;
transport_data = (PMDPCIIOTransportData*) malloc( sizeof( PMDPCIIOTransportData ) );
// set the axis we are talking to with this handle
axis_handle->axis = axis_number;
// set the interface type
axis_handle->InterfaceType = InterfacePCI;
// the transport data is initialized first to setup the defaults
// make sure the IO mode is set correctly
PMDPCI_InitData(transport_data);
// set the board we are talking to with this handle
transport_data->nBoardNo = board_number;
axis_handle->transport_data = (void*) transport_data;
// initialize the transport (inits function pointers)
return PMDPCI_Init(axis_handle);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -