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

📄 ivm_core.c

📁 在嵌入式系统中对Lattice CPLD软件升级时所需的VME文件生成所需源代码。基于E2PROM存储
💻 C
📖 第 1 页 / 共 3 页
字号:
	if ( usDataType & HEAP_IN ) {
		siDataSource = 1;  /*the source of data from memory*/
	}
#ifdef VME_DEBUG
	if ( siDataSource ) {
		printf( "Data is from memory\n" );
	}
	else {
		printf( "Data is from file\n" ); 
	}
#endif
	/*clear the data type register to no data type found first*/
	usDataType &= ~( MASK_DATA + TDI_DATA + TDO_DATA + DMASK_DATA );	
	while ( ( cDataByte = GetByte() ) >= 0 ) { 

#ifdef VME_DEBUG
		for ( iOpcodeIndex = 0; iOpcodeIndex < iOpcodeCount; iOpcodeIndex++ )
			if ( ispVMOpcodes[ iOpcodeIndex ].token == cDataByte ) {
				break;
			}
			printf( "opcode = %s\n", ispVMOpcodes[ iOpcodeIndex ].text );
#endif
			ispVMMemManager( cDataByte, MaxSize );
			switch ( cDataByte ) {
			case TDI:
				usDataType |= TDI_DATA; /*found input data*/
				ispVMData( InData );
				break;
			case XTDO: 
				usDataType |= TDO_DATA;  /*found output data*/
				break;
            case TDO:  
				/*shift out only data found*/               
				/*ensure RAM is in place for data*/
				usDataType |= TDO_DATA;  /*found output data*/
				ispVMData( OutData );
				break;
            case MASK: 
				/*mask data is found*/
				/*ensure RAM is in place for data*/
				usDataType |= MASK_DATA;   /*mask data exist*/
				ispVMData( OutMaskData );
				break;
			case DMASK: 
				/*mask data is found*/
				/*ensure RAM is in place for data*/
				usDataType |= DMASK_DATA;   /*mask data exist*/
				ispVMData( OutDMaskData );
				break;
			case CONTINUE:
				return ( 0 );
			default:      
				/*wrong opcode encountered*/  
				return ( -4 );
			}
			
			/*10/23/01 ht add support to shift right or shift left operation*/
			switch ( cDataByte ) {
			case TDI: 
				if ( usFlowControl & SHIFTLEFT ) {
					ispVMBitShift( SHL, iShiftValue );
					usFlowControl &= ~SHIFTLEFT;
				}
				if ( usFlowControl & SHIFTRIGHT ) {
					ispVMBitShift( SHR, iShiftValue );
					usFlowControl &= ~SHIFTRIGHT;
				}               
			default:
				break;
			}
			
			if ( siDataSource ) {
				usDataType |= HEAP_IN;  /*restore data from memory*/
			}
	}  /*while */
	
	if ( siDataSource ) {  /*fetch data from heap memory upon return*/
		usDataType |= HEAP_IN;
	}
	if ( cDataByte < 0 ) {
		return (-4);  /*invalid code seen*/
	}
	else {
		return (0);
	}
}

/****************************************************************************
                     ispVM Data                         
 Extract one row of data operand from the current data type opcode. Perform
 the decompression if necessary. Extra RAM is not required for the
 decompression process. The decompression scheme employed in this module
 is on row by row basis. The format of the data stream:
 [compression code][compressed data stream]
  0x00    --No compression
  0x01    --Compress by 0x00.
            Example:
            Original stream:   0x000000000000000000000001
            Compressed stream: 0x01000901
            Detail:            0x01 is the code, 0x00 is the key, 
                               0x09 is the count of 0x00 bytes,
                               0x01 is the uncompressed byte.
  0x02    --Compress by 0xFF.
            Example:
            Original stream:   0xFFFFFFFFFFFFFFFFFFFFFF01
            Compressed stream: 0x02FF0901
            Detail:            0x02 is the code, 0xFF is the key, 
                               0x09 is the count of 0xFF bytes,
                               0x01 is the uncompressed byte.
  0x03
  : :
  0xFE   -- Compress by nibble blocks.
            Example:
            Original stream:   0x84210842108421084210
            Compressed stream: 0x0584210
            Detail:            0x05 is the code, means 5 nibbles block.
                               0x84210 is the 5 nibble blocks.
                               The whole row is 80 bits given by usiDataSize.
                               The number of times the block repeat itself
                               is found by usiDataSize/(4*0x05) which is 4.
  0xFF   -- Compress by the most frequently happen byte.
            Example:
            Original stream:   0x04020401030904040404
            Compressed stream: 0xFF04(0,1,0x02,0,1,0x01,1,0x03,1,0x09,0,0,0)
                           or: 0xFF044090181C240
            Detail:            0xFF is the code, 0x04 is the key.
                               a bit of 0 represent the key shall be put into
                               the current bit position and a bit of 1
                               represent copying the next of 8 bits of data
                               in. 

 Global:
    usDataType-----------It specify whether compression is on or not. 
 Return                                                         
    ByteData-----------The data stream from ispVM file     
*****************************************************************************/
void ispVMData( unsigned char * ByteData )
{
	unsigned short size;
	unsigned short i, j, m, index, getData = 0;
	unsigned char cDataByte, compress = 0;
	unsigned short FFcount = 0;
	unsigned char compr_char = 0xFF; 
	char compression=0;
#ifdef VME_DEBUG
	unsigned char FlipData, Data;
#endif
	
	/*convert number in bits to bytes*/
	if (usiDataSize%8>0) {
		size = usiDataSize/8 + 1;
	}
	else {
		size = usiDataSize/8;
	}
	
	/* If there is compression, then check if compress by key of 0x00 or 0xFF
	   or by other keys or by nibble blocks*/
	
	if ( usDataType & COMPRESS ) {
		compression = 1;
		if ( ( ( compress = GetByte() ) == VAR ) && ( usDataType & HEAP_IN ) ) {
			getData = 1;
			usDataType &= ~(HEAP_IN);
			compress = GetByte();
		}
		
		switch (compress){
		case 0x00:  
			/* No compression */
			compression = 0; 
			break;            
		case 0x01:  
			/* Compress by byte 0x00 */
			compr_char = 0x00;
			break;
		case 0x02: 
			/* Compress by byte 0xFF */
			compr_char = 0xFF;  
			break;
		case 0xFF: 
			/* Huffman encoding */
			compr_char = GetByte();
			i = 8;
			for ( index = 0; index < size; index++ ) {
				ByteData[ index ] = 0x00;
				if ( i > 7 ) {
					cDataByte = GetByte(); 
					i = 0;
				}
				if ((cDataByte << i++) & 0x80) 
					m = 8;
				else {
					ByteData[index] = compr_char;
					m = 0;
				}
				
				for (j = 0; j < m; j++) {
					if (i > 7) {
						cDataByte = GetByte(); 
						i = 0;
					}
					ByteData[index] |=((cDataByte << i++)&0x80) >> j;
				} 
			}     
			size = 0;
			break;
		default:   
			for (index = 0; index < size; index++) 
				ByteData[index] = 0x00;
			for (index = 0; index < compress; index++) {
				if (index%2 == 0) 
					cDataByte = GetByte();
				for (i = 0; i < size*2/compress; i++){
					j = index + i*compress;
					/*clear the nibble to zero first*/
					if (j%2) {
						if (index%2) 
							ByteData[j/2] |= cDataByte & 0x0F;
						else 
							ByteData[j/2] |= cDataByte >> 4;
					}
					else {
						if (index%2) 
							ByteData[j/2] |= cDataByte << 4;
						else 
							ByteData[j/2] |= cDataByte & 0xF0;
					}
				}
			}
			size = 0;
			break;
		}
	}
	
	FFcount = 0;
#ifdef VME_DEBUG 
	printf("compress code = %d, compress = %02X, size = %d key=%X\n", compression, compress, usiDataSize, compr_char);
#endif
	/* Decompress by byte 0x00 or 0xFF */
	for (index = 0; index < size; index++) {
		if (FFcount <= 0) {
			cDataByte = GetByte();
			if ((cDataByte == VAR) && (usDataType&HEAP_IN) && !getData && !(usDataType&COMPRESS)) {
				getData = 1;
				usDataType &= ~(HEAP_IN);
				cDataByte = GetByte();
			}
			ByteData[index] = cDataByte; 
			if ((compression) &&(cDataByte == compr_char)) /*decompression is on*/
				FFcount = ispVMDataSize();     /*The number of 0xFF or 0x00 bytes*/
		}
		else {
			FFcount--; /*Use up the 0xFF chain first*/
			ByteData[index] = compr_char;
		}
	}

#ifdef VME_DEBUG 
	if (usiDataSize%8)
		size = usiDataSize/8 + 1;
	else 
		size = usiDataSize/8;
	printf("TDI/TDO data extracted\n");
	
	for (index = size - 1; index >= 0; index--) {
		Data = ByteData[index];
		FlipData = Data;
		for (j=0;j<8;j++) {
			FlipData <<= 1;
			if (Data & 0x1)
				FlipData |= 0x1;
			Data >>= 1;
		}
		printf( "%02X", FlipData );
	}
	printf("\n\n");
#endif
	
	if (getData) {
		usDataType |= HEAP_IN;
		getData = 0;
	}
}

/****************************************************************************
                     ispVM Shift                            
 Perform the function of SIR, SDR and XSDR. It is to shift instruction or
 Data into TDI and/or out of TDO.  
 global:
	usiDataSize----------The size (bits) of the data or instruction to process.                  
              
 Input                                                          
     a_cCode---------------SIR,SDR or XSDR      
 Return                                                         
     cRetCode--------------pass or fail
     
*****************************************************************************/
char ispVMShift( char a_cCode )
{
	unsigned short iDataIndex;
	unsigned short iReadLoop;
	char cRetCode;
	
	cRetCode=0;
	usiDataSize = ispVMDataSize();
#ifdef VME_DEBUG
	printf( "bits size = %d\n", usiDataSize );
#endif

	usDataType &= ~( SIR_DATA + EXPRESS + SDR_DATA );   /*clear the flags first*/
	switch ( a_cCode ) {
	case SIR:
		usDataType |= SIR_DATA;
		/* 1/15/04 If performing cascading, then go directly to SHIFTIR.  Else, 
		   go to IRPAUSE before going to SHIFTIR */
		if ( usFlowControl & CASCADE ) {
			ispVMStateMachine( SHIFTIR );
		}
		else {
			ispVMStateMachine( IRPAUSE );
			ispVMStateMachine( SHIFTIR );
			if ( HeadIR > 0 ){ 
				ispVMBypass( HIR, HeadIR );
				sclock();
			}
		}
		break;
	case XSDR:  
		usDataType |= EXPRESS; /*mark simultaneous in and out*/
    case SDR:   
		usDataType |= SDR_DATA;
		/* 1/15/04 If already in SHIFTDR, then do not move state or shift in header.  
		   This would imply that the previously shifted frame was a cascaded frame.  */
		if ( cCurrentJTAGState != SHIFTDR ) {
			/* 1/15/04 If performing cascading, then go directly to SHIFTDR.  Else, 
		       go to DRPAUSE before going to SHIFTDR */
			if ( usFlowControl & CASCADE ) {
				if ( cCurrentJTAGState == DRPAUSE ) {
					ispVMStateMachine( SHIFTDR );
					/* 1/15/04 If cascade flag has been set and the current state is 
					   DRPAUSE, this implies that the first cascaded frame is about to
					   be shifted in.  The header must be shifted prior to shifting
					   the first cascaded frame. */
					if ( HeadDR > 0 ) {
						ispVMBypass( HDR, HeadDR );
						sclock();
					}

⌨️ 快捷键说明

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