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

📄 cnmutil.c

📁 PEAKAUDIO用于EV2板的MCU控制源码
💻 C
字号:
/*************************************************************************

	CNMUtil.c

  This is the CobraNet Module program utilities file. Utilities include
	an accurate timing function, a hex switch read function, FPGA
	loading routine and some MIB variable support routines.

	Copyright (C) 2001-2004 by Cirrus Logic Inc. All Rights Reserved
*************************************************************************/

#include <8051.h>
#include <intrpt.h>
#include <conio.h>
#include "serial.h"
#include "hostport.h"
#include "command.h"
#include "test.h"
#include "led.h"
#include "mystrings.h"
#include "cnmutil.h"

extern unsigned char gWHICH_MODULE;	//which is present? CM1 or CM2

extern void waiting( unsigned short delay1, unsigned char delay2 )	{
//this routine provides an accurate time delay.
//delay1 and delay2 are passed in registers and those are treated
//separately as chars. see 8051 programming manual for more detail.
//assembly was used to allow for a more controlled way of determining
//the exact time delay. See manual for parameter passing details.
//delay1 and delay2 are passed in registers R3,R4, and R5
//The delay is approx...
//   ( 84 + 48 * ( 3 + R4 + 257 * R5 + R3 * ( 257 + 65536 ) ) ) / clock
//Note: any interrupts will affect the timing.
//Half for six cycle operation. 

     #asm
      x1:
        mov	a,r4
        dec	r4
        bnz	x1
        mov	a,r5
        dec	r5
        bnz	x1
        mov	a,r3
        dec	r3
        bnz	x1
      #endasm
}

extern unsigned short get_hex_switches( unsigned char update_hex )	{
//this routine shifts the contents of the shift registers (HC165)
//supporting the hex switches into the 8051
	unsigned char i;
	static unsigned short hex_value = 0;
	unsigned short bit_value = 1;

	if ( update_hex )	{
		hex_value = 0;
		mHEX_SHIFT = 0;			//load the hex switch data (latch hex switch data)
		mHEX_SHIFT = 1;			//put back into shift mode
		mHEX_DATA_OUT = 0;	//leave zero for now

		//clock the data into the 8051
		for ( i = 0; i < 16; i++ )	{
			if ( mHEX_DATA_IN ) 		//read bit
				hex_value |= bit_value;
			bit_value <<= 1;
			mHEX_CLOCK = 0;		//clock data
			mHEX_CLOCK = 1;
		}
	}
	return( hex_value );
}

extern void set_sysname( void )	{
//sets the SNMP "sysname" variable
   unsigned char error_code;
   unsigned char i,j;
   code char * name_base_ptr = ( code char * ) str_SysName;
   unsigned long name_loc_ptr = cSYSNAME_LOC_ptr; //long but a pointer
   unsigned char dsp_word[ 4 ];
   
			//poke length,last 4 are for the switch value
   error_code = Host_Poke( name_loc_ptr++, cSYS_NAME_LEN + 4 );	//
   for( i = 0; i < ( cSYS_NAME_LEN / gWHICH_MODULE ); i++ )	{
      for( j = 0; j < 4; j++ )
				if ( ( j == 0 ) && ( gWHICH_MODULE == cHOST_CM1 ) )
					dsp_word[ 0 ] = '0';	//set first byte to "zero"
				else
					dsp_word[ j ] = *name_base_ptr++;

      error_code = Host_Poke( name_loc_ptr++, *( ( long * )dsp_word ) );
   }
   //append switch value to system name
   set_syshex( get_hex_switches( cUPDATE_HEX ) );
}

extern void set_syshex( unsigned short syshex_int )	{
//appends switch value in ASCII to MIB variable sysNAME
	unsigned char error_code;
	unsigned long name_loc_ptr = cSYSNAME_LOC_ptr + 1 + 
																( cSYS_NAME_LEN / ( gWHICH_MODULE + 2 ) );
	char * dsp_word_ptr;

	dsp_word_ptr = long2str( ( long ) syshex_int, cLEADING_ZEROS, 
															cFOUR_BYTES );
	if ( gWHICH_MODULE == cHOST_CM1 )	{
					//upper three hex bytes to the right three positions 
		error_code = Host_Poke( name_loc_ptr++, 
														*( ( long * ) ( dsp_word_ptr - 1 ) ) );
						//point to last byte in second MSB position
		error_code = Host_Poke( name_loc_ptr, 
														( *( ( long * ) ( dsp_word_ptr + 2 ) ) ) 
																							& 0xFF0000 );
	}
	else
		error_code = Host_Poke( name_loc_ptr, *( ( long * ) dsp_word_ptr ) );
}

extern void check_hex( void )	{
	unsigned short current_hex;

	current_hex = get_hex_switches( cNO_UPDATE_HEX );
	if ( current_hex != get_hex_switches( cUPDATE_HEX ) )	{
		current_hex = get_hex_switches( cNO_UPDATE_HEX );
		waiting( 0x0C,0x01 );							//wait just a bit for a debounce
			//if still same then keep
		if ( current_hex == get_hex_switches( cUPDATE_HEX ) ) 	;
			set_sysname();
		//otherwise leave with no changes
	}
}

extern void load_FPGA()	{
	unsigned short i;
	code char * xdata_ptr = ( char * ) cFPGA_START_ptr;	//pointer to FPGA data
	far char * xlocation_ptr = ( far char * ) cFPGA_LOC_ptr; //ptr to FPGA
	char * led_ptr = ( char * ) cLED_ptr;
	static near unsigned char fpga_loaded = 0;

	//the following code is needed to establish if the FPGA has already
	//been programmed. When the code starts it moves a bunch of strings
	//into external SRAM but external SRAM is not available until the 
	//FPGA has been loaded. If the FPGA has been loaded the LED registers
	//are available to read and write. A system reset does not affect the
	//FPGA because the 8051 controls the reset to the FPGA so once the FPGA
	//is loaded it stays viable. The code below tests the LED registers and
	//if they don't pass the write/read pattern then a variable is set to
	//direct the 8051 code to reset itself after the FPGA has been loaded.
	*led_ptr++ = 1;
	*led_ptr++ = 0;
	*led_ptr++ = 1;
	led_ptr = ( char * ) cLED_ptr;
	if ( *led_ptr++ == 1 )
		if ( *led_ptr++ == 0 )
			if ( *led_ptr++ == 1 )	{
				led_ptr = ( char * ) cLED_ptr;
				*led_ptr++ = 0;
				*led_ptr++ = 1;
				*led_ptr++ = 0;
				led_ptr = ( char * ) cLED_ptr;
				if ( *led_ptr++ == 0 )
					if ( *led_ptr++ == 1 )
						if ( *led_ptr++ == 0 )
							fpga_loaded = 1;
			}
	
	mFPGA_PROG = 0;
	waiting( 0,0 );		 					//kill a little time, about 11 useconds.
	mFPGA_PROG = 1;							//set init bit to start configuration
	while ( mFPGA_INIT == 0 ) 
		;													//wait for init to go high
	waiting( 0,0 );		 					//kill a little more time
	*xlocation_ptr = 0;					//need to do one bogus write at the start
	for ( i = 0; i < cNUM_XBYTES; i++ )	{
		*xlocation_ptr = *xdata_ptr++;
	}

	if ( !fpga_loaded )	{				//reset the processor,
		#asm
			ljmp 0	
		#endasm		
	}
}

extern unsigned short swapBytes( unsigned short the_short )	{
	return ( ( ( the_short >> 8 ) & 0xFF ) + ( the_short << 8 ) );
}



⌨️ 快捷键说明

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