00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00030 #ifndef SFBPOWER_H
00031 #define SFBPOWER_H
00032
00033 #include "SFBTypes.h"
00034 #include "SFBConstants.h"
00035 #include "SFBAssert.h"
00036
00037 extern int powerDraw();
00038
00039 extern int powerDraw(u32 face);
00040
00041 extern int rawPower(u32 face);
00042
00060 extern s32 faceVoltage(u32 face, bool smoothed = true) ;
00061
00079 extern s32 railVoltage(bool smoothed = true) ;
00080
00081 extern int rawVoltage();
00082
00088 extern void powerOut(u32 face, int on);
00089
00096 extern bool isPowerOut(u32 face);
00097
00098 extern void powerIn(u32 face, int on);
00099
00100
00101 extern void initPowerOuts();
00102
00107 extern void invalidateCalibrationData();
00108
00109 enum ADCSampleIndices {
00110 NORTH_VSENSE_ADC_IDX,
00111 SOUTH_VSENSE_ADC_IDX,
00112 EAST_VSENSE_ADC_IDX,
00113 WEST_VSENSE_ADC_IDX,
00114 VEE_VSENSE_ADC_IDX,
00115 VSENSE_IDX_COUNT,
00116
00117 VCC_VSENSE_ADC_IDX = VSENSE_IDX_COUNT,
00118
00119 NORTH_ISENSE_ADC_IDX,
00120 SOUTH_ISENSE_ADC_IDX,
00121 EAST_ISENSE_ADC_IDX,
00122 WEST_ISENSE_ADC_IDX,
00123 ADC_IDX_COUNT
00124 };
00125
00126 #define ADC_NOMINAL_MV_PER_COUNT 3.22581
00127 #define ADC_FACE_RATIO 10.0
00128 #define ADC_VCC_RATIO 2.0
00129
00130 #define NOMINAL_COUNTS_FOR_MV_FACE(mv) ((u32) (0.5+((mv)/ADC_NOMINAL_MV_PER_COUNT/ADC_FACE_RATIO)))
00131 #define NOMINAL_COUNTS_FOR_MV_VCC(mv) ((u32) (0.5+((mv)/ADC_NOMINAL_MV_PER_COUNT/ADC_VCC_RATIO)))
00132 #define NOMINAL_MV_FOR_COUNT_FACE(count) ((u32) (0.5+((count)*ADC_NOMINAL_MV_PER_COUNT*ADC_FACE_RATIO)))
00133
00134 #define EXTRA_SLOPE_BITS 6
00135 #define UNCALIBRATED_SLOPE_FACE ((u32) ((ADC_NOMINAL_MV_PER_COUNT*ADC_FACE_RATIO)*(1<<EXTRA_SLOPE_BITS)))
00136 #define UNCALIBRATED_CUTOFF 300
00137 #define UNCALIBRATED_INTERCEPT_FACE (UNCALIBRATED_CUTOFF*UNCALIBRATED_SLOPE_FACE)
00138
00139 #define CUTOFF_INDEX 0
00140 #define CUTOFF_BITS 5
00141 #define CUTOFF_CENTER 16
00142 #define CUTOFF_CT_PER_VALUE 10
00143 #define CUTOFF_OFFSET 300
00144
00145 #define INTERCEPT_INDEX (CUTOFF_INDEX+CUTOFF_BITS)
00146 #define INTERCEPT_BITS 5
00147 #define INTERCEPT_CENTER 16
00148 #define INTERCEPT_MV_PER_VALUE 25
00149 #define INTERCEPT_OFFSET -300
00150
00151 #define SLOPE0_INDEX (INTERCEPT_INDEX+INTERCEPT_BITS)
00152 #define SLOPE0_BITS 7
00153 #define SLOPE0_CENTER 64
00154 #define SLOPE0_SCALED_MV_PER_CT_PER_VALUE 10
00155 #define SLOPE0_OFFSET (UNCALIBRATED_SLOPE_FACE+SLOPE0_CENTER*SLOPE0_SCALED_MV_PER_CT_PER_VALUE)
00156
00157 #define SLOPE1_INDEX (SLOPE0_INDEX+SLOPE0_BITS)
00158 #define SLOPE1_BITS 7
00159 #define SLOPE1_CENTER 64
00160 #define SLOPE1_SCALED_MV_PER_CT_PER_VALUE 10
00161 #define SLOPE1_OFFSET (UNCALIBRATED_SLOPE_FACE+SLOPE1_CENTER*SLOPE1_SCALED_MV_PER_CT_PER_VALUE)
00162
00163 struct xcalib {
00164 u32 cutoff;
00165 s32 slope[2];
00166 s32 intercept[2];
00167
00168
00169 void init() {
00170 init(0, UNCALIBRATED_SLOPE_FACE, UNCALIBRATED_SLOPE_FACE, 0);
00171 }
00172
00173 void init(u32 c, s32 m0, s32 m1, s32 b) {
00174 cutoff = c;
00175 slope[0] = m0;
00176 intercept[0] = ((NOMINAL_MV_FOR_COUNT_FACE(c)+b)<<EXTRA_SLOPE_BITS)-m0*c;
00177 slope[1] = m1;
00178 intercept[1] = ((NOMINAL_MV_FOR_COUNT_FACE(c)+b)<<EXTRA_SLOPE_BITS)-m1*c;
00179 }
00180 };
00181 extern xcalib adcCalibs[VSENSE_IDX_COUNT];
00182
00183 struct calibData {
00184
00185 u32 data;
00186 inline u32 getBits(u32 bitIdx, u32 bits) {
00187 return (data>>bitIdx)&((1<<bits)-1);
00188 }
00189 void putBits(u32 bitIdx, u32 bits,u32 value) {
00190 u32 nbits = ((1<<bits)-1);
00191 data &= ~(nbits<<bitIdx);
00192 data |= (value&nbits)<<bitIdx;
00193 }
00194 void init(u32 cutoff, u32 intercept, u32 slope0, u32 slope1) {
00195 putBits(CUTOFF_INDEX,CUTOFF_BITS,cutoff);
00196 putBits(INTERCEPT_INDEX,INTERCEPT_BITS,intercept);
00197 putBits(SLOPE0_INDEX,SLOPE0_BITS,slope0);
00198 putBits(SLOPE1_INDEX,SLOPE1_BITS,slope1);
00199 }
00200 void getFields(u32 & cutoff, u32 & intercept, u32 & slope0, u32 & slope1) {
00201 cutoff = getBits(CUTOFF_INDEX,CUTOFF_BITS);
00202 intercept = getBits(INTERCEPT_INDEX,INTERCEPT_BITS);
00203 slope0 = getBits(SLOPE0_INDEX,SLOPE0_BITS);
00204 slope1 = getBits(SLOPE1_INDEX,SLOPE1_BITS);
00205 }
00206 inline s32 getValue(u32 bitIdx, u32 bits, s32 center, s32 amtPerValue, s32 offset) {
00207 s32 value = getBits(bitIdx,bits);
00208 return (value-center)*amtPerValue+offset;
00209 }
00210 s32 getCutoffCt() {
00211 return getValue(CUTOFF_INDEX,CUTOFF_BITS,CUTOFF_CENTER,CUTOFF_CT_PER_VALUE,CUTOFF_OFFSET);
00212 }
00213 s32 getInterceptMv() {
00214 return
00215 getValue(INTERCEPT_INDEX,INTERCEPT_BITS,INTERCEPT_CENTER,INTERCEPT_MV_PER_VALUE,INTERCEPT_OFFSET);
00216 }
00217 s32 getSlopeScaledMvPerCt(u32 which) ;
00218
00219 void initXcalib(xcalib & x) ;
00220 };
00221
00222 extern void initxcalibsFromGene(u32 gene[VSENSE_IDX_COUNT]) ;
00223
00226 #define VOLTAGE_CALIBRATION_SIZE_BYTES (VSENSE_IDX_COUNT*3)
00227
00228 #define ADC_SCALE_BITS 6
00229 #define WEIGHT_BITS 5
00230 #define UPDATE_SMOOTHED_BUFFER(u16buf,adcScaledData) \
00231 ((u16buf) = (u16) (((((u32)(u16buf))<<WEIGHT_BITS)-(u16buf)+(adcScaledData))>>WEIGHT_BITS))
00232
00233 static inline s32 mapADCCounts(u16 scaledCount, s32 slope, s32 intercept) {
00234 return (((scaledCount*slope)>>ADC_SCALE_BITS)+intercept)>>EXTRA_SLOPE_BITS;
00235 }
00236
00237 extern void unpackCalibrationData(u32 gene[VSENSE_IDX_COUNT], u8 bytes[VOLTAGE_CALIBRATION_SIZE_BYTES]) ;
00238
00239 extern void loadCalibrationData() ;
00240
00241 extern u16 adcLatestSample[ADC_IDX_COUNT];
00242
00243 extern u16 adcSmooth[ADC_IDX_COUNT];
00244
00245 static inline u16 getADCSample(u32 sampleIdx, bool smoothed) {
00246 API_ASSERT_MAX(sampleIdx,ADC_IDX_COUNT);
00247 return smoothed?adcSmooth[sampleIdx]:adcLatestSample[sampleIdx];
00248 }
00249
00250 #define ADC_FLAG_CODE 0x000f
00251 static inline bool isADCSensingEnabled() {
00252 return adcLatestSample[NORTH_ISENSE_ADC_IDX] != ADC_FLAG_CODE;
00253 }
00254 static inline bool isPowerSensingEnabled() {
00255 return adcLatestSample[SOUTH_ISENSE_ADC_IDX] != ADC_FLAG_CODE;
00256 }
00257 extern void setADCSensingEnabled(bool enable) ;
00258 extern void setPowerSensingEnabled(bool enable) ;
00259
00265 extern void initADC();
00271 extern void reinitADC();
00274 #endif