// // $Id: tau.c,v 1.3 1999/11/04 18:00:23 ecueva Exp $ // // Copyright Motorola, Inc. 1997, 1999 ALL RIGHTS RESERVED // // You are hereby granted a copyright license to use, modify, and distribute the // SOFTWARE so long as this entire notice is retained without alteration in any // modified and/or redistributed versions, and that such modified versions are // clearly identified as such. No licenses are granted by implication, estoppel // or otherwise under any patents or trademarks of Motorola, Inc. // // The SOFTWARE is provided on an "AS IS" basis and without warranty. To the // maximum extent permitted by applicable law, MOTOROLA DISCLAIMS ALL WARRANTIES // WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY // OR FITNESS FOR A PARTICULAR PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT // WITH REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF) AND ANY // ACCOMPANYING WRITTEN MATERIALS. // // To the maximum extent permitted by applicable law, IN NO EVENT SHALL MOTOROLA // BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING WITHOUT LIMITATION, DAMAGES // FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS // INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE // THE SOFTWARE. // // Motorola assumes no responsibility for the maintenance and support of the // SOFTWARE. // // History // cc ??????: Created by Chuck Corley, see App Note AN1200. // gm 990602: Modified by GMilliorn to fit DINK command env. // #include #include "errors.h" #include "toks.h" #include "dink.h" #ifdef TAU_SUPPORT // Global calibration value. int TAU_Cal_Value = 0x00000000; #define TAU_INTRPT_BIT 0x80000000 /* THERM1/2[0] = 1 */ #define TAU_INTRPT_VALID 0x40000000 /* THERM1/2[1] = 1 */ #define TAU_RESOLUTION 4 /* 4 degrees C */ #define TAU_THRESHOLD 0x3f800000 /* THERM1/2[2:8] mask */ #define TAU_SPR_VALID 0x1 /* THERM1/2/3[31] = 1 */ #define TAU_SITV_400MHZ 8000 /* Default interval @400MHz */ extern STATUS CommLookChar(); extern void convert_unsigned_char(); extern void Wait1Second( unsigned char *last ); extern int pvr_read(); // Immediate SPR access functions. extern int therm1_read(); extern int therm2_read(); extern int therm3_read(); extern int therm1_write(); extern int therm2_write(); extern int therm3_write(); extern unsigned int CoreFreq; extern unsigned long KEYBOARD; extern long strtol(); /*-------------------------------------------------------------------------- help_tau -- TAU access/control. --------------------------------------------------------------------------*/ void help_tau() { PRINT( "TAU CONTROL\n" "===========\n" "Mnemonic: tau\n" "Syntax: tau [-c cal][-w][-fh]\n" "Description: This command displays or calibrates the TAU (Thermal Assist\n" " Unit). If no option is entered, the current temperature is\n" " displayed (with or without calibration).\n" "Flags: -c Calibrate the TAU to the actual temperature (in ^C).\n" " -w Watch the TAU (until a key is pressed)\n" " -fh Show results in Fahrenheit.\n" ); } /*-------------------------------------------------------------------------- PrintTAUTemp --------------------------------------------------------------------------*/ void PrintTAUTemp( int temp, short DoF ) { int bias = 0; if (DoF) temp = temp * 9 / 5; PRINT("Tjc = %d ^%c", temp, (DoF ? 'F' : 'C')); if (!TAU_Cal_Value) PRINT(" (uncalibrated)"); } /*-------------------------------------------------------------------------- GetTAUTemp -- get the temperature using the TAU. --------------------------------------------------------------------------*/ int GetTAUTemp() { int i; int min_temperature = 0; /* Start at minimum value. */ unsigned long SInterval, threshold; unsigned long Therm1, Therm3, Thermn; /* ** Disable unused THERM2 threshold SPR. */ therm2_write( 0 ); /* ** Determine the sample interval. The result should be 20 microseconds ** based on the core frequency. For example, with a 400 MHz MPC7400, ** SInterval = 20000 (ns) / 2.5 ns, or 8000. */ SInterval = 20000000 / (1000000 / CoreFreq); /* ** Set THERM3 to the sample interval and enable it. */ Therm3 = TAU_Cal_Value | (SInterval << 1) | TAU_SPR_VALID; therm3_write( Therm3 ); /* ** Start with a threshold of one-half of the total range (0-127 degrees), ** or 64 degrees. */ threshold = TAU_RESOLUTION << 4; for (i = 4; i >= 0; i--) { /* ** Put the (new) threshold value in THERM1[2:8] and enable. ** Clear TID bit so that the thermal interrupt bit (TIN) will be set ** when the temperature is above the threshold. */ Therm1 = (threshold << 23) | TAU_SPR_VALID; therm1_write( Therm1 ); /* ** Wait for SITV (Sample Interval Timer) to expire. */ while (!((Thermn = therm1_read()) & TAU_INTRPT_VALID)) ; /* ** Examine the results. If the temperature is greater than the current ** threshold, it becomes the new minimum and the threshold is reduced ** in size. */ if (Thermn & TAU_INTRPT_BIT) { min_temperature = threshold; threshold += TAU_RESOLUTION / 2 << i; } /* Otherwise, the temperature is lower than threshold, so reduce the ** size of the threshold and try again. */ else{ threshold -= TAU_RESOLUTION / 2 << i; } } return(min_temperature + 2); } /*-------------------------------------------------------------------------- CalibrateTAU -- set the calibration value for the Thermal Assist Unit. Undocumented in the MPC750 User's Manual, the TAU can actually be biased by setting reserved bits THERM3[2:6]. THERM3[2] = sign bit (set means subtract the calibration value from threshold) THERM3[3] = adjust by 20 degrees C THERM3[4] = adjust by 8 degrees C THERM3[5] = adjust by 4 degrees C THERM3[6] = adjust by 2 degrees C Enter with a known junction temperature. This routine will call TAU_single_threshold() to determine TAU reading and set the global variable TAU_Cal_Value. As a convention, TAU_Cal_Value bit 31 will be set to a one (valid) to distinguish a calibration value of zero from an uninitialized TAU_Cal_Value. --------------------------------------------------------------------------*/ void CalibrateTAU( int CalTemp ) { extern SetEnv( char*, char*, int ); int difference_error, TAU_measured_value; TAU_Cal_Value = 0; TAU_measured_value = GetTAUTemp(); /* ** Find error = calibration value, then actual will equal measured ** + Cal_Value */ difference_error = CalTemp - TAU_measured_value; /* ** Set TAU_Cal_Value to show that it is valid even if zero. */ TAU_Cal_Value = 1; if (difference_error < 0) { /* What should sign bit be? */ TAU_Cal_Value |= 0x20000000; /* Set sign bit (THERM3[2]) */ difference_error = - difference_error; } if (difference_error >= 20) { /* Is the difference >= 20? */ TAU_Cal_Value |= 0x10000000; /* Set bit (THERM3[3]) */ difference_error -= 20; } if (difference_error >= 8) { /* Is the difference >= 8? */ TAU_Cal_Value |= 0x08000000; /* Set bit (THERM3[4]) */ difference_error -= 8; } if (difference_error >= 4) { /* Is the difference >= 4? */ TAU_Cal_Value |= 0x04000000; /* Set bit (THERM3[5]) */ difference_error -= 4; } if (difference_error >= 2) { /* Is the difference >= 2? */ TAU_Cal_Value |= 0x02000000; /* set bit (THERM3[6]) */ } #ifdef ENV_SUPPORT { char tmp[ 80 ]; convert_unsigned_char( (unsigned int) TAU_Cal_Value, tmp, 16 ); SetEnv( "TAUCAL", tmp, 0 ); } #endif } /*-------------------------------------------------------------------------- par_tau -- TAU control --------------------------------------------------------------------------*/ STATUS par_tau( char *dink_cmd ) { int pvr, temp; long CalTemp; STATUS status; short DoCal, DoWatch, DoF; unsigned char LastSec; TOKEN state; char line[20]; /* ** TAU is only on MPC740, 745, 750, 755, or 7400. */ pvr = pvr_read(); pvr = pvr >> 16; if (pvr != 0x08 && pvr != 0x0C) { PRINT("No Thermal Assist Unit (TAU) on this processor.\n"); return( INVALID ); } /* ** Process other arguments as long as they start with a dash. */ status = SUCCESS; DoCal = 0; DoF = 0; DoWatch = 0; CalTemp = 0; while (tok_is_next_token( DASH_TOK )) { if (tok_is_next_token( BHWD_TOKEN_W )) /* -w */ DoWatch++; else if (tok_is_next_token( BTCL_TOK )) { /* -c cal_temp */ if ((status = tok_get_next_token(&state, line)) == SUCCESS) { CalTemp = strtol(line,(char **)NULL,10); DoCal++; } } else if (tok_is_next_token( FH_TOK )) /* -fh */ DoF++; } /* ** Set the calibration offset. */ if (DoCal) CalibrateTAU( CalTemp ); /* ** Print the temperature once or until a key is pressed. */ LastSec = 0xFF; while (1) { temp = GetTAUTemp(); PrintTAUTemp( temp, DoF ); PRINT("\r"); Wait1Second( &LastSec ); if (!DoWatch) break; if (CommLookChar((char *)KEYBOARD)) break; } PRINT("\n"); return( SUCCESS ); } #endif TAU_SUPPORT