📄 ivm_core.c
字号:
}
else {
ispVMStateMachine( SHIFTDR );
}
}
else {
ispVMStateMachine( DRPAUSE );
ispVMStateMachine( SHIFTDR );
if ( HeadDR > 0 ) {
ispVMBypass( HDR, HeadDR );
sclock();
}
}
}
/*Data is shiftable if usiDataSize is less than MaxSize*/
if ( usiDataSize < MaxSize ) {
rightShift = 1;
}
break;
default:
return (-4);
}
cRetCode = ispVMDataCode();
if ( cRetCode != 0 ) {
return (-4);
}
if ( usDataType & TDO_DATA || usDataType & DMASK_DATA ) {
if(usDataType & DMASK_DATA){
cRetCode = ispVMReadandSave( usiDataSize );
if(!cRetCode){
if ( TailDR > 0 ) {
sclock();
ispVMBypass( TDR, TailDR );
}
ispVMStateMachine( DRPAUSE );
ispVMStateMachine( SHIFTDR );
if( HeadDR > 0 ){
ispVMBypass( HDR, HeadDR );
sclock();
}
for ( iDataIndex=0; iDataIndex < usiDataSize / 8 + 1; iDataIndex++ )
InData[ iDataIndex ] = OutData[ iDataIndex ];
usDataType &= ~( TDO_DATA+ DMASK_DATA );
cRetCode = ispVMSend( usiDataSize );
}
}
else{
cRetCode = ispVMRead( usiDataSize );
if ( cRetCode == -1 && cVendor == XILINX ) {
for( iReadLoop = 0; iReadLoop < 30; iReadLoop++ ){
cRetCode = ispVMRead( usiDataSize );
if( !cRetCode ) {
break;
}
else {
ispVMStateMachine( DRPAUSE ); /*Always DRPAUSE*/
/*Bypass other devices when appropriate*/
ispVMBypass( TDR, TailDR );
ispVMStateMachine( End_DR );
ispVMStateMachine( IDLE );
ispVMDelay( 1000 );
}
}
}
}
}
else { /*TDI only*/
cRetCode = ispVMSend( usiDataSize );
}
/*transfer the input data to the output buffer for the next verify*/
if ( ( usDataType & EXPRESS ) || ( a_cCode == SDR ) ) {
if ( OutData ) {
for ( iDataIndex=0; iDataIndex < usiDataSize / 8 + 1; iDataIndex++ )
OutData[ iDataIndex ] = InData[ iDataIndex ];
}
}
switch( a_cCode ) {
case SIR:
/* 1/15/04 If not performing cascading, then shift ENDIR */
if ( !( usFlowControl & CASCADE ) ) {
if ( TailIR > 0 ) {
sclock();
ispVMBypass( TIR, TailIR );
}
ispVMStateMachine( End_IR );
}
break;
case XSDR:
case SDR:
/* 1/15/04 If not performing cascading, then shift ENDDR */
if ( !( usFlowControl & CASCADE ) ) {
if ( TailDR > 0 ) {
sclock();
ispVMBypass( TDR, TailDR );
}
ispVMStateMachine( End_DR );
}
break;
default:
break;
}
return ( cRetCode );
}
/****************************************************************************
ispVM Amble
This routine is to extract Header and Trailer parameter for SIR and
SDR operations.
The Header and Trailer parameter are the pre-amble and post-amble bit
stream need to be shifted into TDI or out of TDO of the devices. Mostly
is for the purpose of bypassing the leading or trailing devices. ispVM
supports only shifting data into TDI to bypass the devices.
For a single device, the header and trailer parameters are all set to 0
as default by ispVM. If it is for multiple devices, the header and trailer
value will change as specified by the VME file.
Input
Code---------------HIR, HDR, TIR ,TDR.
Return
rcode--------------pass or fail
*****************************************************************************/
char ispVMAmble(char Code)
{
char compress = 0;
usiDataSize = ispVMDataSize();
if (usiDataSize) {
GetByte(); /*discard the TDI opcode*/
/* header and trailers are not compressed */
if (usDataType&COMPRESS) {
usDataType &= ~(COMPRESS);
compress = 1;
}
}
switch (Code) {
case HIR: /*modify the IR length of lead devices*/
HeadIR = usiDataSize;
if (HeadIR){
/*hold the IR opcode for the lead devices*/
ispVMMemManager(HIR, HeadIR);
ispVMData(HIRData);
}
break;
case TIR: /*modify the IR length of the trailing devices*/
TailIR = usiDataSize;
/*hold the IR opcode for the trailing devices*/
if (TailIR){
ispVMMemManager(TIR, TailIR);
ispVMData(TIRData);
}
break;
case HDR: /*modify the DATA length of the lead devices*/
HeadDR = usiDataSize;
/*hold the data stream for the lead devices*/
if (HeadDR){
ispVMMemManager(HDR, HeadDR);
ispVMData(HDRData);
}
break;
case TDR: /*modify the DATA length of the trailing devices*/
TailDR = usiDataSize;
/*hold the data stream for the trailing devices*/
if (TailDR){
ispVMMemManager(TDR, TailDR);
usiDataSize=TailDR;
ispVMData(TDRData);
}
break;
default: break;
}
/* resume compression */
if (compress)
usDataType |= COMPRESS;
if (usiDataSize) { /* Search for CONTINUE */
Code = GetByte();
if (Code == CONTINUE) {
return 0;
}
else {
return -4;
}
}
return 0;
}
/****************************************************************************
ispVM Loop
Perform the function call upon by the REPEAT opcode.
Memory is to be allocated to store the entire loop from REPEAT to ENDLOOP.
After the loop is stored then execution begin. The REPEATLOOP flag is set
on the usFlowControl register to indicate the repeat loop is in session
and therefore fetch opcode from the memory instead of from the file.
global:
pucHeapMemory----------Memory allocated to hold the repeat loop.
iHEAPSize---------The register holds the HEAP memory size.
iHeapCounter------The (byte) pointer to the HEAP.
Input
a_usLoopCount----------the number repeat looping to perform
Return
cRetCode--------------pass or fail
*****************************************************************************/
char ispVMLoop(unsigned short a_usLoopCount)
{
char cRetCode = 0;
unsigned short iHeapIndex = 0;
unsigned short iLoopIndex;
#ifdef VME_DEBUG
static unsigned short iLoopSet = 1;
#endif
iShiftValue = 0;
for ( iHeapIndex = 0; iHeapIndex < iHEAPSize; iHeapIndex++ ) {
pucHeapMemory[ iHeapIndex ] = GetByte();
}
if ( pucHeapMemory[ iHeapIndex - 1 ] != ENDLOOP ) {
return( -4 );
}
usFlowControl |= REPEATLOOP;
usDataType |= HEAP_IN;
#ifdef VME_DEBUG
printf( "\n=====>Begin loop set %d (size = %d).\n", iLoopSet, a_usLoopCount );
#endif
for ( iLoopIndex = 0; iLoopIndex < a_usLoopCount; iLoopIndex++ ) {
iHeapCounter = 0;
#ifdef VME_DEBUG
printf( "\n****Begin repeat loop (%d of %d).****\n", iLoopIndex + 1, a_usLoopCount );
#endif
cRetCode = ispVMCode();
#ifdef VME_DEBUG
printf( "****End repeat loop (%d of %d).****\n", iLoopIndex + 1, a_usLoopCount );
#endif
RepeatLoops++;
if ( cRetCode < 0 ) {
break;
}
}
#ifdef VME_DEBUG
printf( "\n====>Exit loop set %d (size = %d).\n", iLoopSet++, a_usLoopCount );
#endif
usDataType &= ~( HEAP_IN );
usFlowControl &= ~( REPEATLOOP );
return ( cRetCode );
}
/****************************************************************************
ispVMBitShift
Shift the TDI stream left or right by the number of bits. The data in
*InData is of the VME format, so the actual shifting is the reverse of
IEEE 1532 or SVF format.
Input
mode----LSHIFT or RSHIFT
bits----shift left or right by the number bits
The content of *InData is shifted left or right.
*****************************************************************************/
char ispVMBitShift(char mode, unsigned short bits)
{
unsigned short i, size, tmpbits;
#ifdef VME_DEBUG
unsigned short j;
unsigned char FlipData, Data;
#endif
if (usiDataSize%8>0) {
size = usiDataSize/8 + 1;
}
else {
size = usiDataSize/8;
}
switch(mode) {
case SHR:
for (i = 0; i < size; i++) {
if (InData[i] != 0) {
tmpbits = bits;
while (tmpbits > 0) {
InData[i] <<= 1;
if (InData[i] == 0) {
i--;
if (i < 0)
break;
InData[i] = 1;
}
tmpbits--;
}
}
}
break;
case SHL:
for (i = 0; i < size; i++) {
if (InData[i] != 0) {
tmpbits = bits;
while (tmpbits > 0) {
InData[i] >>= 1;
if (InData[i] == 0) {
i--;
if (i < 0)
break;
InData[i] = 8;
}
tmpbits--;
}
}
}
break;
default:
return (-4);
}
#ifdef VME_DEBUG
printf("Address after shifting: \n");
for (i = size - 1; i >= 0; i--) {
Data = InData[i];
FlipData = Data;
for (j=0;j<8;j++) {
FlipData <<= 1;
if (Data & 0x1)
FlipData |= 0x1;
Data >>= 1;
}
printf("%02X", FlipData);
}
printf("\n");
#endif
return (0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -