文章目录
- 1.读MPS5023芯片:0x03ff即将前6位屏蔽
- 2.读PXE1410CDM电压和电流:一个数&0x7ff,将这个数前5位全变为0,其余位不变
- 2.1 1ine11:先看第15和10位,e9b6是上面读出的值
- 2.2 1ine16:PMBUS协议16bit
- 0x20读出0x14:0x14取反加1就是-12
- 0x20读出0x17:0x17取反加1后,十进制和十六进制都为9
- 3. xdpe12284c读电压:https://elixir.bootlin.com/linux/v5.19/source/drivers/hwmon/pmbus/pmbus_core.c#L699,ratio
- 4.xdpe132g5c调压:
- 5.读ADS7830的8个channel电压:P5V0即5.0V
- 6.读INA220电压和电流:Read_INA220_Voltage_Current.sh
1.读MPS5023芯片:0x03ff即将前6位屏蔽
# Read_FPGA_Power.sh
#!/bin/bash
stop_ipmistack()
{
cnt=0
while true
do
/etc/init.d/ipmistack stop >/dev/null 2>&1
s1=$(ps aux)
s2="/usr/local/bin/IPMIMain"
result=$(echo $s1 | grep "${s2}")
if [[ "$result" == "" ]]
then
break
fi
if [ $cnt -eq 5 ]
then
echo "Unable to stop ipmistack !"
exit 1
fi
cnt=$(($cnt+1))
sleep 10
done
}
delete()
{
cnt=0
while true
do
echo 0x73 > /sys/bus/i2c/devices/i2c-7/delete_device #将bus7上0x73这设备删除
if [ $? = 0 ]
then
break
fi
if [ $cnt -eq 5 ]
then
echo "Unable to delete device !"
exit 1
fi
cnt=$(($cnt+1))
done
}
access()
{
cnt=0
while true
do
i2c-test -b 7 -s 0x73 -w -d 0x08 >/dev/null 2>&1
if [ $? = 0 ]
then
break
fi
if [ $cnt -eq 5 ]
then
echo $cnt
echo "Unable to access 9545 !"
exit 1
fi
cnt=$(($cnt+1))
echo $cnt
done
}
OpenChannel()
{
cnt=0
while true
do
i2c-test -b 7 -s 0x71 -w -d 0x80 >/dev/null 2>&1 #0x80打开channel8
if [ $? = 0 ]
then
break
fi
if [ $cnt -eq 5 ]
then
echo "Unable to access 9548 channel8 !"
exit 1
fi
cnt=$(($cnt+1))
done
}
read_voltage(){
cnt=0
while true
do
val_v=$(i2c-test -b 7 -s 0x40 -m 1 -rc 2 -d 0x8b)
if [ $? = 0 ]
then
hexval_v_h=${val_v:14:2}
hexval_v_l=${val_v:17:2}
hexval_v=${hexval_v_l}${hexval_v_h}
#echo $hexval_v #0183
dec_v=$((0x$hexval_v & 0x3ff)) #&:有0为0,3ff:10个1, hex->dec
#echo $dec_v #388
dec_v_wv=$((dec_v*3125)) #31.25mV/LSB
dec_v_v=$((dec_v_wv/100000))
#echo $dec_v_v #12
break
fi
if [ $cnt -eq 5 ]
then
echo "Unable to read voltage !"
exit 1
fi
cnt=$(($cnt+1))
done
}
read_power(){
cnt=0
while true
do
val_a=$(i2c-test -b 7 -s 0x40 -m 1 -rc 2 -d 0x8c) #电流
if [ $? = 0 ]
then
hexval_a_h=${val_a:14:2}
hexval_a_l=${val_a:17:2}
hexval_a=${hexval_a_l}${hexval_a_h}
#echo $hexval_a #0054
dec_a=$((0x$hexval_a & 0x3ff))
dec_a_wa=$((dec_a*6250))
dec_a_a=$((dec_a_wa/100000))
#echo $dec_a_a
power=$(($dec_v_v * $dec_a_a))
echo "FPGA Power : "$power"W"
break
fi
if [ $cnt -eq 5 ]
then
echo "Unable to read electricity !"
exit 1
fi
cnt=$(($cnt+1))
done
}
start_ipmistack()
{
cnt=0
while true
do
/etc/init.d/ipmistack start >/dev/null 2>&1
s1=$(ps aux)
s2="/usr/local/bin/IPMIMain"
result=$(echo $s1 | grep "${s2}")
if [[ "$result" != "" ]]
then
break
fi
if [ $cnt -eq 5 ]
then
echo "Unable to start ipmistack !"
exit 1
fi
cnt=$(($cnt+1))
sleep 10
done
}
start_ipmistack
stop_ipmistack
delete
access
OpenChannel
read_voltage
read_power
start_ipmistack
2.读PXE1410CDM电压和电流:一个数&0x7ff,将这个数前5位全变为0,其余位不变
ipmitool raw 0x3a 0x10 <bus id> <slave addr> <Read count> <Data to write>
(00:第一个状态码不显示)
status , log_psu1 = run_command("sudo bash -c 'a=$(ipmitool raw 0x3a 0x10 14 0xb0 2 0x88) ; b=${a:1:2} ; c=${a:4:5} ; d=${c}${b} ; \
f=`../utility/diag-tools/pmbus_tool/line11 0x$d` ; echo $f'") #psu1输入电压; 输出电压0x8b,line16
status , log_psu2 = run_command("sudo bash -c 'a=$(ipmitool raw 0x3a 0x10 15 0xb0 2 0x88) ; b=${a:1:2} ; c=${a:4:5} ; d=${c}${b} ; \
f=`../utility/diag-tools/pmbus_tool/line11 0x$d` ; echo $f'") #psu2输入电压; 输出电压0x8b,line16
输入电压(mv):
root@gnr5713bb:/var/log/abak# i2cget -f -y 15 0x60 0x88 w
0xe9b6
root@gnr5713bb:/var/log/abak# i2cget -f -y 15 0x61 0x88 w
0xe9b5
root@gnr5713bb:/var/log/abak# i2cget -f -y 15 0x62 0x88 w
0xe9b6
root@gnr5713bb:/var/log/abak# ./line11_arm 0xe9b6
54750
输出电压(mv):
root@gnr5713bb:/var/log/abak# i2cget -f -y 15 0x60 0x8b w
0xc2ad
root@gnr5713bb:/var/log/abak# i2cget -f -y 15 0x61 0x8b w
0xc395
root@gnr5713bb:/var/log/abak# i2cget -f -y 15 0x62 0x8b w
0xc0f8
【VOUT_MODE】:
root@gnr5713bb:/var/log/abak# i2cget -f -y 15 0x60 0x20
0x14
root@gnr5713bb:/var/log/abak# i2cget -f -y 15 0x61 0x20
0x14
root@gnr5713bb:/var/log/abak# i2cget -f -y 15 0x62 0x20
0x14
【输出电压(mv)】:
root@gnr5713bb:/var/log/abak# ./line16_arm 0xc2ad 0x14
12167
root@gnr5713bb:/var/log/abak# ./line16_arm 0xc395 0x14
12223
root@gnr5713bb:/var/log/abak# ./line16_arm 0xc0f8 0x14
12060
2.1 1ine11:先看第15和10位,e9b6是上面读出的值
如下计算机以补码形式存放负数,0010+1=0011(十进制3)。
438乘2的-3次方 = 54.8(V)。
// arm编译器arm-linux-gcc (不是x86的gcc)编译成linear11
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char ** argv)
{
short exponent;
int mantissa;
int val_x;
mantissa = ((signed short)((strtoul(argv[1],0,0) & 0x7ff) << 5)) >> 5;
// printf("%x\n",mantissa);
exponent = ((signed short)strtoul(argv[1],0,0))>>11;
// printf("%d\n",exponent);
val_x = mantissa * 1000L; //v转为mv
if (exponent >= 0)
val_x <<= exponent; // 左移:* 2的exponent次方
else
val_x >>= -exponent; // 右移:/ 2的exponent(正)次方 即 * 2的 - exponent(正)次方
printf("%d\n",val_x);
return 0;
}
2.2 1ine16:PMBUS协议16bit
0x20读出0x14:0x14取反加1就是-12
如下十六进制HEX为c2ad(上面读出的值) ,49837乘2的-12次方 = 12.1(A)。
0x20读出0x17:0x17取反加1后,十进制和十六进制都为9
// linear16
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char ** argv)
{
short exponent;
int mantissa;
int val_x;
mantissa = (signed short)strtoul(argv[1],0,0);
exponent = ((signed short)(0x17 << 11)) >> 11 ;
val_x = mantissa * 1000L;
if (exponent >= 0)
val_x <<= exponent;
else
val_x >>= -exponent;
printf("%d\n",val_x);
return 0;
}
linear16_convert()
{
mantissa=$(printf %d "$1") # 有符号,也需像linear11_convert一样判断
if [ $((($2 >> 4) & 0x1)) == 1 ] ; then
exponent=$(((((($2 << 11)) >> 11)) & 0xf))
exponent=$(($exponent ^ 0xf))
exponent=$((~$exponent))
else
exponent=$(printf %d "$2")
fi
val_x=$((mantissa * 1000))
if [ $exponent -ge 0 ]; then
val_x=$(($val_x<<$exponent))
else
val_x=$(($val_x>>$((-$exponent))))
fi
echo $val_x
}
# Read_PXE1410CDM_0X62_Voltage_Current.sh
#!/bin/bash
write_ch0()
{
cnt=0
while true
do
i2c-test -b 7 -s 0x60 -w -d 0x0 0x00 >/dev/null 2>&1
if [ $? = 0 ]
then
break
fi
if [ $cnt -eq 5 ]
then
echo "Unable to write PXE CH0!"
exit 1
fi
cnt=$(($cnt+1))
done
}
read_ch0_voltage(){
cnt=0
while true
do
val_v_0=$(i2c-test -b 7 -s 0x60 -m 1 -rc 2 -d 0x8b)
if [ $? = 0 ]
then
hex_v_h_0=${val_v_0:14:2}
hex_v_l_0=${val_v_0:17:2}
hex_v_0=${hex_v_l_0}${hex_v_h_0}
dec_v_0=$((0x$hex_v_0 & 0xff))
#echo $dec_v_0
dec_v_0=$(((500 + (dec_v_0 - 1) * 10)/2))
echo "PXE_0x60_0_P0V9_VCCH Voltage : "$dec_v_0"mV"
break
fi
if [ $cnt -eq 5 ]
then
echo "Unable to read ch0 voltage !"
exit 1
fi
cnt=$(($cnt+1))
done
}
read_ch0_current(){
cnt=0
while true
do
val_a_0=$(i2c-test -b 7 -s 0x60 -m 1 -rc 2 -d 0x8c)
if [ $? = 0 ]
then
hex_a_h_0=${val_a_0:14:2}
hex_a_l_0=${val_a_0:17:2}
hex_a_0=${hex_a_l_0}${hex_a_h_0}
dec_a_0=$(./linear11 0x$hex_a_0)
echo "PXE_0x60_0 Current : "$dec_a_0"mA"
break
fi
if [ $cnt -eq 5 ]
then
echo "Unable to read ch0 current !"
exit 1
fi
cnt=$(($cnt+1))
done
}
start_ipmistack
stop_ipmistack
delete
access
OpenChannel
write_ch0
read_ch0_voltage
read_ch0_current
write_ch1
read_ch1_voltage
read_ch1_current
start_ipmistack
3. xdpe12284c读电压:https://elixir.bootlin.com/linux/v5.19/source/drivers/hwmon/pmbus/pmbus_core.c#L699,ratio
// linux-aspeed/drivers/hwmon/pmbus/xdpe12284.c
static int xdpe122_identify(struct i2c_client *client,
struct pmbus_driver_info *info)
{
u8 vout_params;
int i, ret;
for (i = 0; i < XDPE122_PAGE_NUM; i++) {
/* Read the register with VOUT scaling value.*/
ret = pmbus_read_byte_data(client, i, PMBUS_VOUT_MODE); // PMBUS_VOUT_MODE=0x20 , ret=0x21(page01) , ret=0x23(page00默认)
if (ret < 0)
return ret;
vout_params = ret & GENMASK(4, 0); // 0010 0011 & 0001 1111 = 0000 0011 (0x03)
switch (vout_params) {
case XDPE122_PROT_VR12_5_10MV: // 0x02
info->vrm_version[i] = vr13;
break;
case XDPE122_PROT_VR12_5MV: // 0x01
info->vrm_version[i] = vr12;
break;
case XDPE122_PROT_IMVP9_10MV: // 0x03 //
info->vrm_version[i] = imvp9;
break;
case XDPE122_AMD_625MV: // 0x10
info->vrm_version[i] = amd625mv;
break;
default:
return -EINVAL;
}
}
return 0;
}
// linux-aspeed/drivers/hwmon/pmbus/pmbus_core.c
static long pmbus_reg2data_vid(struct pmbus_data *data,
struct pmbus_sensor *sensor)
{
long val = sensor->data;
long rv = 0;
switch (data->info->vrm_version[sensor->page]) {
case vr11:
if (val >= 0x02 && val <= 0xb2)
rv = DIV_ROUND_CLOSEST(160000 - (val - 2) * 625, 100);
break;
case vr12:
if (val >= 0x01)
rv = 250 + (val - 1) * 5;
break;
case vr13:
if (val >= 0x01)
rv = 500 + (val - 1) * 10;
break;
case imvp9:
if (val >= 0x01)
rv = 200 + (val - 1) * 10; // val就是0x8b读出的值,10就是10mv步进
break;
case amd625mv:
if (val >= 0x0 && val <= 0xd8)
rv = DIV_ROUND_CLOSEST(155000 - val * 625, 100);
break;
}
return rv;
}
4.xdpe132g5c调压:
如下在switch芯片手册中,查找到AVS值需要经过intel VR11.1协议进行转换。
如下在intel VRM11.1协议说明手册中通过Vcc_Max一列看出步长为6.25mv。Hex一列代表switch芯片传入basecpld的初始值,Hex为00的Vcc_Max的值为1.6+0.00625*2=1.6125(V),通过i2cget -f -y 0 0x0d 0x10从basecpld的10寄存器读取switch芯片传入的初始值为0x7a,所以Hex为7a的Vcc_Max值 = 1.6125 -(0.00625*122)= 0.85
(V),所以0.85V为最终的XDPE132g芯片的调压显示结果值。
但是XDPE132g芯片内部有调压逻辑如下,所以不能将0.85直接设置进XDPE132g芯片寄存器中,厂商邮件如下:
通过i2cget -f -y 29 0x40 0x20命令读出XDPE132g芯片的20寄存器为0x14对应如上0.244mv step,上图第三步1000 (mv) / 1.953 = 512即0x0200(相当于3484),所以850 (mv) / 0.244 = 3484,将3484设置进21寄存器(需要先切换page),再通过8b寄存器读出对比设置进21寄存器的值是否一致。
关闭dcdc监控后,可以看出XDPE132g芯片的8b和21寄存器的值是一样的。
// cat /sys/bus/i2c/devices/i2c-29/29-0040/hwmon/hwmon20/in2_input节点后
// linux-aspeed/drivers/hwmon/pmbus/pmbus_core.c
static ssize_t pmbus_show_sensor(struct device *dev,
struct device_attribute *devattr, char *buf)
{
struct pmbus_data *data = pmbus_update_device(dev);
struct pmbus_sensor *sensor = to_pmbus_sensor(devattr);
if (sensor->data < 0)
return sensor->data;
if (sensor->data == 0xffff)
return 0;
printk(KERN_INFO "pmbus_show_sensor, %d, %d\n", sensor->data, pmbus_reg2data(data, sensor)); /// 3282, 801
return snprintf(buf, PAGE_SIZE, "%ld\n", pmbus_reg2data(data, sensor));
}
static long pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor)
{
long val;
switch (data->info->format[sensor->class]) {
case direct:
val = pmbus_reg2data_direct(data, sensor);
break;
case vid:
val = pmbus_reg2data_vid(data, sensor);
break;
case linear:
printk(KERN_INFO "pmbus_reg2datalinear\n"); // 会打印出
default:
printk(KERN_INFO "pmbus_reg2datadefault, %d, %d\n", sensor->page, sensor->reg); // 0 , 139 (8b)
val = pmbus_reg2data_linear(data, sensor);
break;
}
return val;
}
static long pmbus_reg2data_linear(struct pmbus_data *data,
struct pmbus_sensor *sensor)
{
s16 exponent;
s32 mantissa;
long val;
printk(KERN_INFO "pmbus_reg2datad_data, %d\n", sensor->data); // 3282
if (sensor->class == PSC_VOLTAGE_OUT) { /* LINEAR16 */
exponent = data->exponent[sensor->page];
mantissa = (u16) sensor->data;
} else { /* LINEAR11 */
exponent = ((s16)sensor->data) >> 11;
mantissa = ((s16)((sensor->data & 0x7ff) << 5)) >> 5;
}
val = mantissa;
/* scale result to milli-units for all sensors except fans */
if (sensor->class != PSC_FAN)
val = val * 1000L;
/* scale result to micro-units for power sensors */
if (sensor->class == PSC_POWER)
val = val * 1000L;
if (exponent >= 0)
val <<= exponent;
else
val >>= -exponent;
printk(KERN_INFO "pmbus_reg2data_val, %d\n", val); // 801
return val;
}
5.读ADS7830的8个channel电压:P5V0即5.0V
如下CH0:1000 1100为六进制0x8c,十进制140。从SD=1往下看,SD=0不用看。CH1中C2 C1 C0为1 0 0即0xcc即204。
cmd | (((ch >> 1) | (ch & 0x01) << 2) << 4); cmd =0x8c。
如下CH7竖着多出了一条。
i2c-test -b 7 -s 0x48 -rc 1 -d 0x8c #显示0x57即十进制87。如下x=87*9766,divisor=1000。
#define DIV_ROUND_CLOSEST(x, divisor)({ //C文件
typeof(x) __x = x;
typeof(divisor) __d = divisor;
(((typeof(x))-1) > 0 ||
((typeof(divisor))-1) > 0 ||
(((__x) > 0) == ((__d) > 0))) ?
(((__x) + ((__d) / 2)) / (__d)) :
(((__x) - ((__d) / 2)) / (__d));
})
# Read_ADS7830_0x48_Voltage.sh
#!/bin/bash
DIV_ROUND_CLOSEST(){
__x=$1
__d=$2
A=$(((__x) > 0))
B=$(((__d) > 0))
C=$(($__d>>1))
C=$(($__x+$C))
C=$(($C/$__d))
D=$(($__d>>1))
D=$(($__x+$D))
D=$(($D/$__d))
E=$(($A==$B))
echo $(($E?$C:$D))
}
OpenChannel()
{
cnt=0
while true
do
i2c-test -b 7 -s 0x71 -w -d 0x04 >/dev/null 2>&1
if [ $? = 0 ]
then
break
fi
if [ $cnt -eq 5 ]
then
echo "Unable to access 9548 channel 3 !"
exit 1
fi
cnt=$(($cnt+1))
done
}
read_channel0(){
cnt=0
while true
do
val_0=$(i2c-test -b 7 -s 0x48 -rc 1 -d 0x8c) # channel1 :不是0x8c,是0xcc(204).....
if [ $? = 0 ]
then
#echo $val_0
hex_0=${val_0:34:2}
#echo $hex_0 #57
dec_0=$((0x$hex_0 & 0xff)) #转为十进制
#echo $dec_0 #87
dec_v_0=$((dec_0*9766))
dec_v_v_0=$(DIV_ROUND_CLOSEST $dec_v_0 1000)
echo "ADS7830 CH0:PFM8_VCC Voltage : "$dec_v_v_0"mV"
break
fi
if [ $cnt -eq 5 ]
then
echo "Unable to read channel0 voltage !"
exit 1
fi
cnt=$(($cnt+1))
done
}
read_channel7(){
cnt=0
while true
do
val_7=$(i2c-test -b 7 -s 0x48 -rc 1 -d 0xfc)
if [ $? = 0 ]
then
#echo $val_7
hex_7=${val_7:34:2}
#echo $hex_7 #57
dec_7=$((0x$hex_7 & 0xff))
#echo $dec_7 #
dec_v_7=$((dec_7*9766))
dec_v_v_7=$(($(DIV_ROUND_CLOSEST $dec_v_7 1000)*2)) # 多出一条
echo "ADS7830 CH7:P3V3_EARLY Voltage : "$dec_v_v_7"mV"
break
fi
if [ $cnt -eq 5 ]
then
echo "Unable to read channel7 voltage !"
exit 1
fi
cnt=$(($cnt+1))
done
}
start_ipmistack
stop_ipmistack
delete
access
OpenChannel
read_channel0
...
read_channel7
start_ipmistack
# Read_ADS7830_0X49_Voltage.sh
#!/bin/bash
read_channel0(){
cnt=0
while true
do
val_0=$(i2c-test -b 7 -s 0x49 -rc 1 -d 0x8c)
if [ $? = 0 ]
then
#echo $val_0
hex_0=${val_0:34:2}
#echo $hex_0 #57
dec_0=$((0x$hex_0 & 0xff))
#echo $dec_0 #87
dec_v_0=$((dec_0*9766))
dec_v_v_0=$(($(DIV_ROUND_CLOSEST $dec_v_0 1000)*2))
echo "ADS7830 CH0:P2V5_VPP_CH01 Voltage : "$dec_v_v_0"mV"
break
fi
if [ $cnt -eq 5 ]
then
echo "Unable to read channel0 voltage !"
exit 1
fi
cnt=$(($cnt+1))
done
}
read_channel6(){
cnt=0
while true
do
val_6=$(i2c-test -b 7 -s 0x49 -rc 1 -d 0xbc)
if [ $? = 0 ]
then
#echo 6
hex_6=${val_6:34:2}
#echo $hex_6 #57
dec_6=$((0x$hex_6 & 0xff))
#echo $dec_6 #
dec_v_6=$((dec_6*9766))
dec_v_v_6=$(($(DIV_ROUND_CLOSEST $dec_v_6 1000)*349/100))
echo "ADS7830 CH6:P5V0 Voltage : "$dec_v_v_6"mV"
break
fi
if [ $cnt -eq 5 ]
then
echo "Unable to read channel6 voltage !"
exit 1
fi
cnt=$(($cnt+1))
done
}
read_channel7(){
cnt=0
while true
do
val_7=$(i2c-test -b 7 -s 0x49 -rc 1 -d 0xfc)
if [ $? = 0 ]
then
#echo $val_7
hex_7=${val_7:34:2}
#echo $hex_7 #57
dec_7=$((0x$hex_7 & 0xff))
#echo $dec_7 #
dec_v_7=$((dec_7*9766))
dec_v_v_7=$(($(DIV_ROUND_CLOSEST $dec_v_7 1000)*57/10))
echo "ADS7830 CH7:P12V Voltage : "$dec_v_v_7"mV"
break
fi
if [ $cnt -eq 5 ]
then
echo "Unable to read channel7 voltage !"
exit 1
fi
cnt=$(($cnt+1))
done
}
start_ipmistack
stop_ipmistack
delete
access
OpenChannel
read_channel0
...
read_channel6
read_channel7
start_ipmistack
6.读INA220电压和电流:Read_INA220_Voltage_Current.sh
#!/bin/bash
delete()
{
cnt=0
while true
do
echo 0x73 > /sys/bus/i2c/devices/i2c-3/delete_device
if [ $? = 0 ]
then
break
fi
if [ $cnt -eq 5 ]
then
echo "Unable to delete device !"
exit 1
fi
cnt=$(($cnt+1))
done
}
OpenChannel()
{
cnt=0
while true
do
i2c-test -b 3 -s 0x71 -w -d 0x02 >/dev/null 2>&1
if [ $? = 0 ]
then
break
fi
if [ $cnt -eq 5 ]
then
echo "Unable to access 9548 channel2 !"
exit 1
fi
cnt=$(($cnt+1))
done
}
read_voltage(){
cnt=0
while true
do
val_v=$(i2c-test -b 3 -s 0x41 -m 1 -rc 2 -d 0x02)
if [ $? = 0 ]
then
#echo $val_v #08 aa
hexval_v_h=${val_v:14:2}
hexval_v_l=${val_v:17:2}
hexval_v=${hexval_v_h}${hexval_v_l}
dec_v_v=$((0x$hexval_v>>3))
dec_v_v=$(($dec_v_v<<2))
echo "INA220 Voltage : "$dec_v_v"mV"
break
fi
if [ $cnt -eq 5 ]
then
echo "Unable to read INA220 voltage !"
exit 1
fi
cnt=$(($cnt+1))
done
}
DIV_ROUND_CLOSEST(){
if [ $# -ne 2 ]
then
echo 0
else
__x=$1
__d=$2
A=$(((__x) > 0))
B=$(((__d) > 0))
C=$(($__d>>1))
C=$(($__x+$C))
C=$(($C/$__d))
D=$(($__d>>1))
D=$(($__x+$D))
D=$(($D/$__d))
E=$(($A==$B))
echo $(($E?$C:$D))
fi
}
Read_Reg()
{
val=$(i2c-test -b 3 -s 0x41 -m 1 -rc 2 -d $1)
val_h=${val:14:2}
val_l=${val:17:2}
val=${val_h}${val_l}
echo $val
}
start_ipmistack()
{
cnt=0
while true
do
/etc/init.d/ipmistack start >/dev/null 2>&1
s1=$(ps aux)
s2="/usr/local/bin/IPMIMain"
result=$(echo $s1 | grep "${s2}")
if [[ "$result" != "" ]]
then
break
fi
if [ $cnt -eq 5 ]
then
echo "Unable to start ipmistack !"
exit 1
fi
cnt=$(($cnt+1))
sleep 10
done
}
start_ipmistack
stop_ipmistack
delete
access
OpenChannel
read_voltage
i2c-test -b 3 -s 0x41 -w -d 0x05 0x03 0x7f >/dev/null 2>&1 #0x37f上面的校正值
config_shunt_div=100
dividend=$(DIV_ROUND_CLOSEST 1000000000 $config_shunt_div)
shunt_val=$(Read_Reg 0x01)
current_lsb_uA=$(DIV_ROUND_CLOSEST $dividend 0x$shunt_val)
current_val=$(Read_Reg 0x04)
ret=$((0x$current_val * $current_lsb_uA))
ret=$(DIV_ROUND_CLOSEST $ret 1000)
echo "INA220 Current : "$ret"mA"
start_ipmistack