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

📄 ivm_core.c

📁 在嵌入式系统中对Lattice CPLD软件升级时所需的VME文件生成所需源代码。基于E2PROM存储
💻 C
📖 第 1 页 / 共 3 页
字号:
				}
				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 + -