#define STX104_INTRA_SAMPLE_TIMING 5000 /* nanoseconds */ #define STX104_TIME_RESOLUTION 25 /* nanoseconds */ /*################################################################################## * ANALOG INPUT TIMING FUNCTIONS */ /***************************************************************** / ANALOG INPUT MINIMUM SETTLING TIME */ static unsigned long STX104_AI_Time_Settling_Minimum( float ai_capacitance_pf, float ai_resistance_ohms ) { unsigned long settle_time_ns; //settle_time = ai_resistance_ohms * ai_capacitance_pf * pow10(-12) * 16 * ln(2) * pow10(9) settle_time_ns = (unsigned long) ( ai_resistance_ohms * ai_capacitance_pf * pow10(-3) * 16 * log(2) ); return( settle_time_ns ); } /***************************************************************** / ANALOG INPUT 8254 TIMING */ static void STX104_AI_Timing_8254_Set( int board, long time_interval_ns ) { long high_count; long low_count; unsigned int octet; STX104_Set_Bank( board, 0 ); /* assumes 10MHz clock (i.e. no 1MHz jumper) */ low_count = 10L; /* 1 microsecond intervals */ high_count = time_interval_ns / 1000; while ( high_count > 65536L ) { high_count = high_count >> 1; low_count = low_count << 1; } while ( high_count < 2L ) { high_count = high_count << 1; low_count = low_count >> 1; } /* set counter/timer 2 */ outportb( stx104_base_address[board] + STX104_CT_CONFIGURATION, 0xB4 ); octet = ((unsigned int) high_count) & 0x00FF; outp( stx104_base_address[board] + STX104_CT2_DATA, octet ); octet = ((unsigned int) high_count) >> 8; outp( stx104_base_address[board] + STX104_CT2_DATA, octet ); /* set counter/timer 1 */ outportb( stx104_base_address[board] + STX104_CT_CONFIGURATION, 0x74 ); octet = ((unsigned int) low_count) & 0x00FF; outp( stx104_base_address[board] + STX104_CT1_DATA, octet ); octet = ((unsigned int) low_count) >> 8; outp( stx104_base_address[board] + STX104_CT1_DATA, octet ); } /***************************************************************** / ANALOG INPUT GENERAL TIMING */ static void STX104_AI_Timing_Set( int board, unsigned long ai_time_frame_ns, unsigned long ai_time_intra_sample_ns ) { unsigned int adc_burst_channel_count; switch ( stx104_revision[board] ) { case STX104_REVISION_080214: STX104_Set_Bank( board, 1 ); STX104_Write_Indexed_Data_Byte( board, STX104_BURST_FUNCTION_ENABLE_INDEXED, 0x40 ); STX104_Write_Indexed_Data_Byte( board, STX104_BURST_MODE_ENABLE_INDEXED, 0x40 ); STX104_Write_Indexed_Data_Byte( board, STX104_CONVERSION_DISABLE_INDEXED, 0x00 ); adc_burst_channel_count = (unsigned char)( 0x0F & ( stx104_ai_channel_last[board] - stx104_ai_channel_first[board] ) ); adc_burst_channel_count = adc_burst_channel_count << 4; outp( stx104_base_address[board] + STX104_PACER_CLOCK_CONTROL, adc_burst_channel_count ); /* the following registers require the number of 25nSec intervals to achieve the selected timing */ STX104_Write_Indexed_Data_Dword( board, STX104_ANALOG_INPUT_FRAME_TIMER, ( ai_time_frame_ns/STX104_TIME_RESOLUTION ) ); STX104_Write_Indexed_Data_Dword( board, STX104_ANALOG_INPUT_BURST_TIMER, ( (ai_time_intra_sample_ns - STX104_INTRA_SAMPLE_TIMING) / STX104_TIME_RESOLUTION ) ); break; default: if ( ai_time_intra_sample_ns > STX104_INTRA_SAMPLE_TIMING /*nS*/ ) { /* cannot use adc-burst mode */ STX104_AI_Timing_8254_Set( board, ai_time_intra_sample_ns ); outp( stx104_base_address[board] + STX104_BURST_FUNCTION, 0x00 ); outp( stx104_base_address[board] + STX104_BURST_MODE_ENABLE, 0x00 ); outp( stx104_base_address[board] + STX104_CONVERSION_DISABLE, 0x00 ); } else { /* utilize adc-burst mode */ STX104_AI_Timing_8254_Set( board, ai_time_frame_ns ); outp( stx104_base_address[board] + STX104_BURST_FUNCTION, 0x40 ); outp( stx104_base_address[board] + STX104_BURST_MODE_ENABLE, 0x40 ); outp( stx104_base_address[board] + STX104_CONVERSION_DISABLE, 0x00 ); adc_burst_channel_count = (unsigned char)( 0x0F & ( stx104_ai_channel_last[board] - stx104_ai_channel_first[board] ) ); adc_burst_channel_count = adc_burst_channel_count << 4; outp( stx104_base_address[board] + STX104_PACER_CLOCK_CONTROL, adc_burst_channel_count ); } } }