/* CMX 8 Channel Voltage Monitor Divider Resistors Created: 7-Dec-2013 This program is used to calculate the resistor values for the Power OK Monitor Circuit on the CMX card. The CMX Power OK Monitor uses 2 Analog Devices type ADM12914 Quad Hi/Low Monitor ICs. The reference Voltage in the ADM12914 is 0.5 Volts and is accurate to within better than 1% of this value. The 8 CMX supplies that are monitored are: Data Sheet Allowed Supply Name Nominal Value Range for Normal Operation ----------- ------------- ---------------------------- BULK_5V0 5.000 Volts 4.725 : 5.250 --> +- 5.0% BULK_3V3 3.300 3.000 : 3.600 --> +- 9.0% * BULK_2V5 2.500 2.375 : 2.625 --> +- 5.0% BF_CORE 1.000 0.950 : 1.050 --> +- 5.0% TP_CORE 1.000 0.950 : 1.050 --> +- 5.0% BSPT_CORE 1.200 1.140 : 1.260 --> +- 5.0% GTX_AVCC 1.030 1.000 : 1.060 --> +- 2.9% @ GTX_AVTT 1.200 1.140 : 1.260 --> +- 5.0% Notes: * Although some of the 3.3V parts on the CMX card can run with a +- 9% power supply we will limit the allowed range of the BULK_3V3 supply to +- 5%. @ This GTX_AVCC supply has the most critical tolerance. It also has a anticipated voltage drop of about 25 mV on its path to the Base Function FPGA (due to fill routing resistance and filter inductor resistance). Thus we will probably tune the output of this supply to 1.055 Volts. ADM12914 Characteristics: - The accuracy of the 0.500 Volt reference for the UnderVolt and OverVolt Comparators is 0.496 to 0.504 Volts, i.e. +- 0.80% - The offsets of these comparators are not specified. - Threshold accuracy is specified as +- 0.80% - The Input Bias Current of these comparators is specified as +- 10 nAmp max. - Example circuits are shown with resistor voltage dividers carrying 5 uAmp standing current. Limits on the Voltage Divider Standing Current: - From the above we clearly want at least 5 uAmps of standing current in the resistor voltage dividers. - We are using 0805 resistors in the voltage dividers. These have a power rating of 125 mW and we probably do not want to run them at over 25 mW. In each divider it is the upper resistor Rx that has the maximum heat dissipation of the 3 resistors in a given divider chain. Nominal Rx Volt I Limit Minimum Rx Supply Name Voltage Drop for 25 mW for 25 mW ----------- ------- ------- --------- ---------- BULK_5V0 5.000 4.500 V 5.55 mA 810 Ohms BULK_3V3 3.300 2.800 8.93 314 BULK_2V5 2.500 2.000 12.50 160 BF_CORE 1.000 0.500 50.00 10 TP_CORE 1.000 0.500 50.00 10 BSPT_CORE 1.200 0.700 35.71 20 GTX_AVCC 1.030 0.530 47.17 11 GTX_AVTT 1.200 0.700 35.71 20 - For 0.5% resolution in selection the voltage divider resistors we probably need to stay at values of 200 Ohms or more. - The reference designators of the 24 resistors in the Voltage Monitor voltage dividers are: Rx Ry Rz Top Mid Gnd Supply Name Ohms Ohms Ohms ----------- ------ ------ ------ BULK_5V0 R1882 R1883 R1884 BULK_3V3 R1864 R1865 R1866 BULK_2V5 R1861 R1862 R1863 BF_CORE R1876 R1877 R1878 TP_CORE R1867 R1868 R1869 BSPT_CORE R1879 R1880 R1881 GTX_AVCC R1870 R1871 R1872 GTX_AVTT R1873 R1874 R1875 GTX Supply Note: - Recall that the BF and TP FPGAs share a common pair of GTX power supply modules. There is separate LC filtering between these power supply modules and the BF GTX loads and the TP GTX loads. - Recall that all monitoring of the GTX voltages is done at the GTX supply module outputs, i.e. the LC filter inputs (not at the BF or TP GTX loads). - For a nominal BF FPGA GTX load, the voltage drop from the GTX supply module output to the BF GTX loads is expected to be about: GTX_AVCC Voltage Drop to Base Function Load = ?? mV GTX_AVTT Voltage Drop to Base Function Load = ?? mV - The nominal output voltage of the GTX_AVCC and the GTX_AVTT supply modules will be set HI by the values shown above. - Once the CMX cards are in operation that actual voltage at the BF and TP GTX loads needs to be measured and the GTX supply module outputs setup accordingly. This program asks the user for the desired standing current in each of the 8 voltage monitor divider circuit and then prints out: - The 24 resistor values to use so that the monitor circuit will say Power is OK, if all supplies are within the specified output range, and assuming ideal value resistors. - The 24 resistor values to use so that the monitor circuit will say Power is OK, if all supplies are within the specified output range, and none of the resistors are of the wrong value by more than +- 1%. */ #include #include #define BULK_5V0_NOMINAL 5.000 #define BULK_5V0_TOLERANCE 0.050 #define BULK_3V3_NOMINAL 3.300 #define BULK_3V3_TOLERANCE 0.050 #define BULK_2V5_NOMINAL 2.500 #define BULK_2V5_TOLERANCE 0.050 #define BF_CORE_NOMINAL 1.000 #define BF_CORE_TOLERANCE 0.050 #define TP_CORE_NOMINAL 1.000 #define TP_CORE_TOLERANCE 0.050 #define BSPT_CORE_NOMINAL 1.200 #define BSPT_CORE_TOLERANCE 0.050 #define GTX_AVCC_NOMINAL 1.055 /* note the special vailue */ #define GTX_AVCC_TOLERANCE 0.029 #define GTX_AVTT_NOMINAL 1.200 #define GTX_AVTT_TOLERANCE 0.050 float calc_resistor_Rx( float Voltage_Nominal, float Voltage_Tolerance, float Standing_Current_Nominal_mA ) ; float calc_resistor_Ry( float Voltage_Nominal, float Standing_Current_Nominal_mA, float Rx_Calcd_Value, float Rz_Calcd_Value ) ; float calc_resistor_Rz( float Voltage_Tolerance, float Standing_Current_Nominal_mA ) ; main() { float Standing_Nom_mA, V_Nom, V_Tol ; float Rx_Rtnd, Ry_Rtnd, Rz_Rtnd ; /* BULK_5V0 Calculation */ printf(" \n \n \n ") ; printf("Enter the BULK_5V0 resistor divider nominal current (mAmps) : "); scanf( "%f", &Standing_Nom_mA ) ; printf(" \n ") ; V_Nom = BULK_5V0_NOMINAL ; V_Tol = BULK_5V0_TOLERANCE ; Rx_Rtnd = calc_resistor_Rx( V_Nom, V_Tol, Standing_Nom_mA ) ; Rz_Rtnd = calc_resistor_Rz( V_Tol, Standing_Nom_mA ) ; Ry_Rtnd = calc_resistor_Ry( V_Nom, Standing_Nom_mA, Rx_Rtnd, Rz_Rtnd ) ; /* Print the BULK_5V0 information. */ printf( "The BULK_5V0 voltage tolerance is = %5.3f Volts \n", V_Nom ) ; printf( " The tolerance on the BULK_5V0 output voltage is = %4.1f percent \n", ( V_Tol * 100.0 ) ) ; printf( " The value of BULK_5V0_Rx = %7.2f Ohms \n", Rx_Rtnd ) ; printf( " The value of BULK_5V0_Ry = %7.2f Ohms \n", Ry_Rtnd ) ; printf( " The value of BULK_5V0_Rz = %7.2f Ohms \n", Rz_Rtnd ) ; /* BULK_3V3 Calculation */ printf(" \n \n \n ") ; printf("Enter the BULK_3V3 resistor divider nominal current (mAmps) : "); scanf( "%f", &Standing_Nom_mA ) ; printf(" \n ") ; V_Nom = BULK_3V3_NOMINAL ; V_Tol = BULK_3V3_TOLERANCE ; Rx_Rtnd = calc_resistor_Rx( V_Nom, V_Tol, Standing_Nom_mA ) ; Rz_Rtnd = calc_resistor_Rz( V_Tol, Standing_Nom_mA ) ; Ry_Rtnd = calc_resistor_Ry( V_Nom, Standing_Nom_mA, Rx_Rtnd, Rz_Rtnd ) ; /* Print the BULK_3V3 information. */ printf( "The nominal BULK_3V3 output voltage is = %5.3f Volts \n", V_Nom ) ; printf( " The BULK_3V3 output voltage tolerance is = %4.1f percent \n", ( V_Tol * 100.0 ) ) ; printf( " The value of BULK_3V3_Rx = %7.2f Ohms \n", Rx_Rtnd ) ; printf( " The value of BULK_3V3_Ry = %7.2f Ohms \n", Ry_Rtnd ) ; printf( " The value of BULK_3V3_Rz = %7.2f Ohms \n", Rz_Rtnd ) ; /* BULK_2V5 Calculation */ printf(" \n \n \n ") ; printf("Enter the BULK_2V5 resistor divider nominal current (mAmps) : "); scanf( "%f", &Standing_Nom_mA ) ; printf(" \n ") ; V_Nom = BULK_2V5_NOMINAL ; V_Tol = BULK_2V5_TOLERANCE ; Rx_Rtnd = calc_resistor_Rx( V_Nom, V_Tol, Standing_Nom_mA ) ; Rz_Rtnd = calc_resistor_Rz( V_Tol, Standing_Nom_mA ) ; Ry_Rtnd = calc_resistor_Ry( V_Nom, Standing_Nom_mA, Rx_Rtnd, Rz_Rtnd ) ; /* Print the BULK_2V5 information. */ printf( "The nominal BULK_2V5 output voltage is = %5.3f Volts \n", V_Nom ) ; printf( " The BULK_2V5 output voltage tolerance is = %4.1f percent \n", ( V_Tol * 100.0 ) ) ; printf( " The value of BULK_2V5_Rx = %7.2f Ohms \n", Rx_Rtnd ) ; printf( " The value of BULK_2V5_Ry = %7.2f Ohms \n", Ry_Rtnd ) ; printf( " The value of BULK_2V5_Rz = %7.2f Ohms \n", Rz_Rtnd ) ; /* BF_CORE Calculation */ printf(" \n \n \n ") ; printf("Enter the BF_CORE resistor divider nominal current (mAmps) : "); scanf( "%f", &Standing_Nom_mA ) ; printf(" \n ") ; V_Nom = BF_CORE_NOMINAL ; V_Tol = BF_CORE_TOLERANCE ; Rx_Rtnd = calc_resistor_Rx( V_Nom, V_Tol, Standing_Nom_mA ) ; Rz_Rtnd = calc_resistor_Rz( V_Tol, Standing_Nom_mA ) ; Ry_Rtnd = calc_resistor_Ry( V_Nom, Standing_Nom_mA, Rx_Rtnd, Rz_Rtnd ) ; /* Print the BF_CORE information. */ printf( "The nominal BF_CORE output voltage is = %5.3f Volts \n", V_Nom ) ; printf( " The BF_CORE output voltage tolerance is = %4.1f percent \n", ( V_Tol * 100.0 ) ) ; printf( " The value of BF_CORE Rx = %7.2f Ohms \n", Rx_Rtnd ) ; printf( " The value of BF_CORE Ry = %7.2f Ohms \n", Ry_Rtnd ) ; printf( " The value of BF_CORE Rz = %7.2f Ohms \n", Rz_Rtnd ) ; /* TP_CORE Calculation */ printf(" \n \n \n ") ; printf("Enter the TP_CORE resistor divider nominal current (mAmps) : "); scanf( "%f", &Standing_Nom_mA ) ; printf(" \n ") ; V_Nom = TP_CORE_NOMINAL ; V_Tol = TP_CORE_TOLERANCE ; Rx_Rtnd = calc_resistor_Rx( V_Nom, V_Tol, Standing_Nom_mA ) ; Rz_Rtnd = calc_resistor_Rz( V_Tol, Standing_Nom_mA ) ; Ry_Rtnd = calc_resistor_Ry( V_Nom, Standing_Nom_mA, Rx_Rtnd, Rz_Rtnd ) ; /* Print the TP_CORE information. */ printf( "The nominal TP_CORE output voltage is = %5.3f Volts \n", V_Nom ) ; printf( " The TP_CORE output voltage tolerance is = %4.1f percent \n", ( V_Tol * 100.0 ) ) ; printf( " The value of TP_CORE Rx = %7.2f Ohms \n", Rx_Rtnd ) ; printf( " The value of TP_CORE Ry = %7.2f Ohms \n", Ry_Rtnd ) ; printf( " The value of TP_CORE Rz = %7.2f Ohms \n", Rz_Rtnd ) ; /* BSPT_CORE Calculation */ printf(" \n \n \n ") ; printf("Enter the BSPT_CORE resistor divider nominal current (mAmps) : "); scanf( "%f", &Standing_Nom_mA ) ; printf(" \n ") ; V_Nom = BSPT_CORE_NOMINAL ; V_Tol = BSPT_CORE_TOLERANCE ; Rx_Rtnd = calc_resistor_Rx( V_Nom, V_Tol, Standing_Nom_mA ) ; Rz_Rtnd = calc_resistor_Rz( V_Tol, Standing_Nom_mA ) ; Ry_Rtnd = calc_resistor_Ry( V_Nom, Standing_Nom_mA, Rx_Rtnd, Rz_Rtnd ) ; /* Print the BSPT_CORE information. */ printf( "The nominal BSPT_CORE output voltage is = %5.3f Volts \n", V_Nom ) ; printf( " The BSPT_CORE output voltage tolerance is = %4.1f percent \n", ( V_Tol * 100.0 ) ) ; printf( " The value of BSPT_CORE Rx = %7.2f Ohms \n", Rx_Rtnd ) ; printf( " The value of BSPT_CORE Ry = %7.2f Ohms \n", Ry_Rtnd ) ; printf( " The value of BSPT_CORE Rz = %7.2f Ohms \n", Rz_Rtnd ) ; /* GTX_AVCC Calculation */ printf(" \n \n \n ") ; printf("Enter the GTX_AVCC resistor divider nominal current (mAmps) : "); scanf( "%f", &Standing_Nom_mA ) ; printf(" \n ") ; V_Nom = GTX_AVCC_NOMINAL ; V_Tol = GTX_AVCC_TOLERANCE ; Rx_Rtnd = calc_resistor_Rx( V_Nom, V_Tol, Standing_Nom_mA ) ; Rz_Rtnd = calc_resistor_Rz( V_Tol, Standing_Nom_mA ) ; Ry_Rtnd = calc_resistor_Ry( V_Nom, Standing_Nom_mA, Rx_Rtnd, Rz_Rtnd ) ; /* Print the GTX_AVCC information. */ printf( "The nominal GTX_AVCC output voltage is = %5.3f Volts \n", V_Nom ) ; printf( " The GTX_AVCC output voltage tolerance is = %4.1f percent \n", ( V_Tol * 100.0 ) ) ; printf( " The value of GTX_AVCC Rx = %7.2f Ohms \n", Rx_Rtnd ) ; printf( " The value of GTX_AVCC Ry = %7.2f Ohms \n", Ry_Rtnd ) ; printf( " The value of GTX_AVCC Rz = %7.2f Ohms \n", Rz_Rtnd ) ; /* GTX_AVTT Calculation */ printf(" \n \n \n ") ; printf("Enter the GTX_AVTT resistor divider nominal current (mAmps) : "); scanf( "%f", &Standing_Nom_mA ) ; printf(" \n ") ; V_Nom = GTX_AVTT_NOMINAL ; V_Tol = GTX_AVTT_TOLERANCE ; Rx_Rtnd = calc_resistor_Rx( V_Nom, V_Tol, Standing_Nom_mA ) ; Rz_Rtnd = calc_resistor_Rz( V_Tol, Standing_Nom_mA ) ; Ry_Rtnd = calc_resistor_Ry( V_Nom, Standing_Nom_mA, Rx_Rtnd, Rz_Rtnd ) ; /* Print the GTX_AVTT information. */ printf( "The nominal GTX_AVTT output voltage is = %5.3f Volts \n", V_Nom ) ; printf( " The GTX_AVTT output voltage tolerance is = %4.1f percent \n", ( V_Tol * 100.0 ) ) ; printf( " The value of GTX_AVTT Rx = %7.2f Ohms \n", Rx_Rtnd ) ; printf( " The value of GTX_AVTT Ry = %7.2f Ohms \n", Ry_Rtnd ) ; printf( " The value of GTX_AVTT Rz = %7.2f Ohms \n", Rz_Rtnd ) ; } /* Function calc_resistor_Rx This is the function to calculate the Rx resistor based on the user specificed nominal voltage divider standing current and the nominal power supply voltage and the required voltage tolerance. */ float calc_resistor_Rx( float Voltage_Nom, float Voltage_Tol, float Standing_Current_Nom_mA ) { float Under_Volt_LIM, Under_Volt_Stand_I ; float Stand_Current_Nom, Rx_calc ; /* Calculate the Rx value based on its requirements for the UnderVolt Threshold Limit, R = E/I with E being the difference between the UnderVolt Limit and the 0.500 Volt Comparator Threshold and I being the Nominal Standing Current reduced by the Voltage Tolerance. */ Stand_Current_Nom = Standing_Current_Nom_mA / 1000.0 ; Under_Volt_LIM = Voltage_Nom * ( 1.000 - Voltage_Tol ) ; Under_Volt_Stand_I = Stand_Current_Nom * ( 1.000 - Voltage_Tol ) ; Rx_calc = (Under_Volt_LIM - 0.500) / Under_Volt_Stand_I ; return (Rx_calc) ; } /* Function calc_resistor_Rz This is the function to calculate the Rx resistor based on the user specificed nominal voltage divider standing current and the nominal power supply voltage and the required voltage tolerance. */ float calc_resistor_Rz( float Voltage_Tol, float Standing_Current_Nom_mA ) { float Stand_Current_Nom, Over_Volt_Stand_I, Rz_calc ; /* Now calculate the Rz value based on its requirements for the OverVolt Threshold Limit, R = E/I with E being the 0.500 Volt comparator threshold and I being the Nominal Standing Current increased by the Voltage Tolerance. */ Stand_Current_Nom = Standing_Current_Nom_mA / 1000.0 ; Over_Volt_Stand_I = Stand_Current_Nom * ( 1.000 + Voltage_Tol ) ; Rz_calc = 0.500 / Over_Volt_Stand_I ; return (Rz_calc) ; } /* Function calc_resistor_Ry This is the function to calculate the Ry resistor based on the values of Rx and Rz and the nominal standing current. */ float calc_resistor_Ry( float Voltage_Nom, float Standing_Current_Nom_mA, float Rx_Value, float Rz_Value ) { float Stand_Current_Nom, work_value_1, Ry_calc ; /* Now calculate the Ry value based on the sum of Rx + Ry + Rz pulling the specified nominal current when the specified nominal power supply voltage is put across the. R = E/I */ Stand_Current_Nom = Standing_Current_Nom_mA / 1000.0 ; work_value_1 = Voltage_Nom / Stand_Current_Nom ; Ry_calc = work_value_1 - ( Rx_Value + Rz_Value ) ; return (Ry_calc) ; }