nicsensor/nicsensor.sh

1318 lines
39 KiB
Bash
Executable File

#!/bin/sh
# ---------------------------------------------------------
# Project Feature Varible (Change as need)
# ---------------------------------------------------------
# ADC128 Division factor
votage_division_factor_0="1"
votage_division_factor_1="1"
votage_division_factor_2="1"
votage_division_factor_3="0.8"
votage_division_factor_4="0.6"
votage_division_factor_5="0.6"
votage_division_factor_6="0.2326"
votage_division_factor_7="1"
# ADC128 channel name
ADC128_Channel0_name="Channel0"
ADC128_Channel1_name="Channel1"
ADC128_Channel2_name="Channel2"
ADC128_Channel3_name="Channel3"
ADC128_Channel4_name="Channel4"
ADC128_Channel5_name="Channel5"
ADC128_Channel6_name="Channel6"
ADC128_Channel7_name="Channel7"
# INA3221 shunt resistor(unit: mohm)
shunt_resistor_0="2"
shunt_resistor_1="2"
shunt_resistor_2="5"
# INA3221 channel name
INA3221_Channel0_name="Channel0"
INA3221_Channel1_name="Channel1"
INA3221_Channel2_name="Channel2"
# EMC1413 channel name
EMC1413_Channel0_name="Channel0"
EMC1413_Channel1_name="Channel1"
EMC1413_Channel2_name="Channel2"
# TMP468 channel name
TMP468_Channel0_name="Local"
TMP468_Channel1_name="Remote1"
TMP468_Channel2_name="Remote2"
TMP468_Channel3_name="Remote3"
TMP468_Channel4_name="Remote4"
TMP468_Channel5_name="Remote5"
TMP468_Channel6_name="Remote6"
TMP468_Channel7_name="Remote7"
TMP468_Channel8_name="Remote8"
# TMP112 sensor name
TMP112_Sensor_name="Temperature"
# fru basic offset
fru_offset="0x00 0x00"
Support_Sensor_List="emc1413, adc128, ina3221, tmp468, tmp112"
Support_Server_List="5280m7, 5468m7, donghu, yichun, qiandaohu"
# Which server will use this script
server_type="5280m7"
# ---------------------------------------------------------
# Common Varible (Don't Change)
# ---------------------------------------------------------
# Input Param
nic_slot=$1
sensor_type=$2
# Introduction of chip_slave
# 1.chip i2c slave address(7bit)
chip_slave=$3
option_data=$4
option_data2=$5
# CHIP REGISTER
REG_pca9641_controll="0x01"
REG_adc128_config="0x00"
REG_adc128_advance="0x0b"
REG_adc128_status="0x0c"
REG_adc128_ch0="0x20"
REG_adc128_ch1="0x21"
REG_adc128_ch2="0x22"
REG_adc128_ch3="0x23"
REG_adc128_ch4="0x24"
REG_adc128_ch5="0x25"
REG_adc128_ch6="0x26"
REG_adc128_ch7="0x27"
REG_emc1413_TD1_H="0x00"
REG_emc1413_TD1_L="0x29"
REG_emc1413_TD2_H="0x01"
REG_emc1413_TD2_L="0x10"
REG_emc1413_TD3_H="0x23"
REG_emc1413_TD3_L="0x24"
REG_ina3221_ch1="0x01"
REG_ina3221_ch2="0x03"
REG_ina3221_ch3="0x05"
REG_ina3221_bus1="0x02"
REG_ina3221_bus2="0x04"
REG_ina3221_bus3="0x06"
REG_tmp112="0x00"
REG_tmp468="0x80"
# ---------------------------------------------------------
# Global Varible (Don't Change)
# ---------------------------------------------------------
# DEBUG MODE=0 : Disable debug mode
# =1 : Enable debug mode
DEBUG_MODE=0
i2c_bus=12
pca9641_slave=0x41
pca9548_channel=0x04
pca9548_slave=0x72
is_have_pca9641=1
log="/tmp/nicsensor_debug.log"
INA3221_SHUNT_VOLT=0
INA3221_BUS_VOLT=1
INA3221_POWER=2
INFO="Info"
WARNING="Warning"
ERROR="Error"
ina3221_ch0_volt="0"
ina3221_ch1_volt="0"
ina3221_ch2_volt="0"
ina3221_ch0_current="0"
ina3221_ch1_current="0"
ina3221_ch2_current="0"
SCRIPT_VERSION="1.3 Standard Rev1"
fru_file_name=$option_data2
fru_write_size=0
fru_write_data=""
nic_type=""
slot_number=""
res_tmp468=""
# ---------------------------------------------------------
# Script Function Defination
# ---------------------------------------------------------
print_ocp_usage(){
echo "----------------------------------------------------------------"
echo " To test OCP Nic on server, support command as:"
echo " 1.detect function"
echo " ./nicsensor.sh detect ocp"
echo " 2.Reading sensors"
echo " ./nicsensor.sh ocp0 emc1413 0x4c"
echo ""
echo " Now only 5280m7 support to test ocp card"
echo ""
}
# script usage
print_usage(){
echo ""
echo "================>>> nicsensor script usage <<<=================="
echo " Command Format : ./nicsensor.sh [slot] [sensor tpye] [slave]"
echo " Option Detail"
echo " [slot] : 0 1 2 3 4 5 ..."
echo " [sensor type] : $Support_Sensor_List"
echo " [slave] : chip slave address , please provide 7 bit address"
echo " E.G. : ./nicsensor.sh 1 adc128 0x1f"
echo " ./nicsensor.sh pcie1 ina3221 0x42"
echo " ./nicsensor.sh ocp0 emc1413 0x4c"
echo ""
echo " To Auto detect i2c slave on server, please use:"
echo " ./nicsensor.sh detect"
echo " ./nicsensor.sh detect pcie"
echo " ./nicsensor.sh detect ocp [some server don't support]"
echo " This function now only support on server:"
echo " $Support_Server_List"
echo ""
echo " If want to read/write chip register, use the below format"
echo " ./nicsensor.sh [slot] chip [slave] [i2c_command]"
echo " i2c_command : such as [i2ctransfer -y 13 w1@0x10 0x00 r2]"
echo ""
echo " If want to use debug mode, please modify the DEBUG_MODE to 1"
echo " now status : DEBUG_MODE = $DEBUG_MODE"
print_ocp_usage
}
print_chip_command_format(){
echo "Command Format : ./nicsensor.sh [slot] chip [slave] [i2c_command]"
}
print_fru_command_format(){
echo "Command Format : ./nicsensor.sh [slot] fru [slave] write [fru_file]"
}
# print format message to console
# @Param1 message level [Info Warning Error]
# @Param2 message content
format_print(){
echo ">>> [$1] $2"
}
# print format message to log file
# @Param1 message level [Info Warning Error]
# @Param2 message content
format_log_print(){
echo "[$1] $2" >> $log
}
# switch pca9548 channels then do i2cdetect one times
# @Param1 i2c bus number
# @Param2 pca9548 slave address
# @Param3 pca9548 channel hex value
# @Param4 pca9548 channel
# @Param5 pcie slot number
do_i2c_detect(){
if [ $nic_type == "ocp" ];then
format_print $INFO "OCP slot $5 : bus$1 9548channel$4"
else
format_print $INFO "PCIe slot $5 : bus$1 9548channel$4"
fi
i2ctransfer -y $1 w1@$2 $3
i2cdetect -y $1
}
# script self test
conf_pre_check(){
# check DEBUG_MODE value
if [ $DEBUG_MODE -ne 0 ] && [ $DEBUG_MODE -ne 1 ];then
format_print $ERROR "Invalid conf value, DEBUG_MODE: $DEBUG_MODE"
exit 1
fi
}
set_configuration_5280m7(){
# set pca9641 address && I2C BUS
if [ $nic_type == "ocp" ];then
is_have_pca9641=0
pca9548_slave="0x70"
i2c_bus=3
else
is_have_pca9641=1
if [ $slot_number -le 2 ];then
pca9641_slave="0x41"
pca9548_slave="0x72"
i2c_bus=12
else
pca9641_slave="0x42"
pca9548_slave="0x72"
i2c_bus=13
fi
fi
# set pca9548 switch channel
if [ $nic_type == "ocp" ];then
if [ $slot_number -eq 0 ];then
pca9548_channel="0x01"
elif [ $slot_number -eq 1 ];then
pca9548_channel="0x02"
elif [ $slot_number -eq 2 ];then
pca9548_channel="0x04"
else
format_print $WARNING "Unspecified card slot!"
fi
else
if [ $slot_number -eq 0 ];then
pca9548_channel="0x02"
elif [ $slot_number -eq 1 ];then
pca9548_channel="0x04"
elif [ $slot_number -eq 2 ];then
pca9548_channel="0x08"
elif [ $slot_number -eq 3 ];then
pca9548_channel="0x02"
elif [ $slot_number -eq 4 ];then
pca9548_channel="0x04"
elif [ $slot_number -eq 5 ];then
pca9548_channel="0x08"
else
format_print $WARNING "Unspecified card slot!"
fi
fi
}
set_configuration_5468m7(){
is_have_pca9641=1
# set pca9641 address && I2C BUS
if [ $slot_number -le 4 ];then
pca9641_slave="0x31"
pca9548_slave="0x70"
i2c_bus=13
else
pca9641_slave="0x42"
pca9548_slave="0x71"
i2c_bus=14
fi
# set pca9548 switch channel
if [ $slot_number -eq 0 ];then
pca9548_channel="0x01"
elif [ $slot_number -eq 1 ];then
pca9548_channel="0x02"
elif [ $slot_number -eq 2 ];then
pca9548_channel="0x04"
elif [ $slot_number -eq 3 ];then
pca9548_channel="0x08"
elif [ $slot_number -eq 4 ];then
pca9548_channel="0x10"
elif [ $slot_number -eq 5 ];then
pca9548_channel="0x01"
elif [ $slot_number -eq 6 ];then
pca9548_channel="0x02"
elif [ $slot_number -eq 7 ];then
pca9548_channel="0x04"
elif [ $slot_number -eq 8 ];then
pca9548_channel="0x08"
elif [ $slot_number -eq 9 ];then
pca9548_channel="0x10"
elif [ $slot_number -eq 10 ];then
pca9548_channel="0x20"
else
format_print $WARNING "Unspecified card slot!"
fi
}
set_configuration_donghu(){
is_have_pca9641=0
i2c_bus=3
pca9548_slave="0x70"
# set pca9548 switch channel
if [ $slot_number -eq 0 ];then
pca9548_channel="0x80"
elif [ $slot_number -eq 1 ];then
pca9548_channel="0x40"
elif [ $slot_number -eq 2 ];then
pca9548_channel="0x20"
elif [ $slot_number -eq 3 ];then
pca9548_channel="0x10"
elif [ $slot_number -eq 4 ];then
pca9548_channel="0x08"
elif [ $slot_number -eq 5 ];then
pca9548_channel="0x04"
elif [ $slot_number -eq 6 ];then
pca9548_channel="0x02"
elif [ $slot_number -eq 7 ];then
pca9548_channel="0x01"
else
format_print $WARNING "Unspecified card slot!"
fi
}
set_configuration_yichun(){
is_have_pca9641=0
pca9548_slave="0x74"
# set pca9548 switch channel
if [ $slot_number -eq 0 ];then
i2c_bus=12
pca9548_channel="0x02"
elif [ $slot_number -eq 1 ];then
i2c_bus=13
pca9548_channel="0x02"
elif [ $slot_number -eq 2 ];then
i2c_bus=14
pca9548_channel="0x02"
else
format_print $WARNING "Unspecified card slot!"
fi
}
set_configuration_qiandaohu(){
is_have_pca9641=0
if [ $slot_number -le 7 ];then
i2c_bus=3
pca9548_slave=0x70
else
i2c_bus=6
pca9548_slave=0x71
fi
# set pca9548 switch channel
if [ $slot_number -eq 0 ];then
pca9548_channel="0x08"
elif [ $slot_number -eq 1 ];then
pca9548_channel="0x04"
elif [ $slot_number -eq 2 ];then
pca9548_channel="0x01"
elif [ $slot_number -eq 3 ];then
pca9548_channel="0x02"
elif [ $slot_number -eq 4 ];then
pca9548_channel="0x80"
elif [ $slot_number -eq 5 ];then
pca9548_channel="0x40"
elif [ $slot_number -eq 6 ];then
pca9548_channel="0x10"
elif [ $slot_number -eq 7 ];then
pca9548_channel="0x20"
elif [ $slot_number -eq 8 ];then
pca9548_channel="0x08"
elif [ $slot_number -eq 9 ];then
pca9548_channel="0x04"
elif [ $slot_number -eq 10 ];then
pca9548_channel="0x01"
elif [ $slot_number -eq 11 ];then
pca9548_channel="0x02"
else
format_print $WARNING "Unspecified card slot!"
fi
}
# Get nic type and slot number
parse_nic_slot(){
fullname=0
case $nic_slot in
ocp*)
nic_type="ocp"
;;
pcie*)
nic_type="pcie"
fullname=1
;;
*)
nic_type="pcie"
fullname=0;
;;
esac
if [ $nic_type == "ocp" ];then
slot_number=$(echo $nic_slot | cut -c 4)
else
if [ $fullname -eq 1 ];then
slot_number=$(echo $nic_slot | cut -c 5)
else
slot_number=$nic_slot
fi
fi
format_log_print $INFO "Nic Type : $nic_type"
format_log_print $INFO "Slot Num : $slot_number"
}
# Base on the server type, set i2c conf
set_configuration(){
format_log_print $INFO "Server Type : $server_type"
parse_nic_slot
case $server_type in
"5280m7")
# Support PCIe and OCP configuration
set_configuration_5280m7
;;
"5468m7")
set_configuration_5468m7
;;
"donghu")
set_configuration_donghu
;;
"yichun")
set_configuration_yichun
;;
"qiandaohu")
set_configuration_qiandaohu
;;
*)
format_print $ERROR "Error: Unsupport Server Type !!! - $server_type"
format_print $INFO "Support list: $Support_Server_List"
exit 1
;;
esac
}
init_debuglog(){
# only save one running log
if [ -e $log ];then
rm $log
fi
# print time header
res_date=`date +%Y-%m-%dT%H:%M:%S`
format_log_print $INFO "Start Time : $res_date"
format_log_print $INFO "Script Version : $SCRIPT_VERSION"
if [ $DEBUG_MODE -ne 0 ];then
format_log_print $WARNING "Enable debug mode : $DEBUG_MODE"
fi
}
# Before start test, record configurtion to log
record_config_info(){
format_log_print $INFO "PCIE slot : $nic_slot"
format_log_print $INFO "I2C Bus: $i2c_bus"
if [ $is_have_pca9641 -eq 1 ];then
format_log_print $INFO "PCA9641 slave: $pca9641_slave"
fi
format_log_print $INFO "PCA9548 slave: $pca9548_slave"
format_log_print $INFO "PCA9548 channel: $pca9548_channel"
# Record i2c device info to log
format_log_print $INFO "At the beginning, I2C bus status:"
res_info=`i2cdetect -y $i2c_bus`
echo $res_info >> $log
}
get_pca9641_control(){
# Request 9641 lock
res_lock=`i2ctransfer -y $i2c_bus w2@$pca9641_slave $REG_pca9641_controll 0x81 r1`
format_log_print $INFO "After request 9641 lock, The REG value is $res_lock"
# Build 9641 Connection
res_build=`i2ctransfer -y $i2c_bus w2@$pca9641_slave $REG_pca9641_controll 0x85 r1`
format_log_print $INFO "After Build 9641 connection, The REG value is $res_build"
# After get 9641 controll, Record i2c device info to log
res_after=`i2cdetect -y $i2c_bus`
echo $res_after >> $log
if [ "$res_build" != "0x87" ];then
format_print $ERROR "Cannot establish connection with pca9641 !!!"
exit 1
fi
}
switch_pca9548_channel(){
# set 9548 channel
res_setchannel=`i2ctransfer -y $i2c_bus w1@$pca9548_slave $pca9548_channel`
format_log_print $INFO "After switch channel"
# After set 9548 channel , record i2c device info
res_after=`i2cdetect -y $i2c_bus`
echo $res_after >> $log
}
# ---------------------------------------------------------
# Chip EMC1413
# ---------------------------------------------------------
# process sensor data then print to console
# @Param1 emc1413 data high 8bit
# @Param2 emc1413 data low 8bit
# @Param3 customization channel name
convert_emc1413_data(){
# remove data prefix '0x'
hex_value1=$(echo "$1" | awk '{sub(/^0x/,""); print}')
hex_value2=$(echo "$2" | awk '{sub(/^0x/,""); print}')
# bc calculator recognized upper case only, change data to upper case
upper_hex_value1=$(echo "$hex_value1" | awk '{
for(i=1; i<=length($0); i++){
if(tolower(substr($0,i,1)) ~ /^[a-f]$/)
printf toupper(substr($0,i,1));
else
printf substr($0,i,1);
}
print ""
}')
upper_hex_value2=$(echo "$hex_value2" | awk '{
for(i=1; i<=length($0); i++){
if(tolower(substr($0,i,1)) ~ /^[a-f]$/)
printf toupper(substr($0,i,1));
else
printf substr($0,i,1);
}
print ""
}')
# change data from hex to dec
dec_value1=$(echo "ibase=16; $upper_hex_value1" | bc)
dec_value2=$(echo "ibase=16; $upper_hex_value2" | bc)
# calculate tempreture
temp=$(echo "scale=4; $dec_value1 + ($dec_value2 / 32 * 0.125 )" | bc)
# print result to consol
format_temp=$(echo "$temp" | awk '{ if ($0 ~ /^\./) print "0" $0; else print $0 }')
echo "$3 : $format_temp C, hex value : $hex_value1 $hex_value2"
}
# Get the sensor data, then parse raw data
read_emc1413_channel_value(){
format_log_print $INFO "Start EMC1413 channel data ..."
res_td1_h=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_emc1413_TD1_H r1`
res_td1_l=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_emc1413_TD1_L r1`
res_td2_h=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_emc1413_TD2_H r1`
res_td2_l=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_emc1413_TD2_L r1`
res_td3_h=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_emc1413_TD3_H r1`
res_td3_l=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_emc1413_TD3_L r1`
# record i2c raw data to log
format_log_print $INFO "channel 1 : $res_td1_h $res_td1_l"
format_log_print $INFO "channel 2 : $res_td2_h $res_td2_l"
format_log_print $INFO "channel 3 : $res_td3_h $res_td3_l"
# start parse raw data
echo ">>> The emc1413 value is:"
convert_emc1413_data $res_td1_h $res_td1_l "$EMC1413_Channel0_name"
convert_emc1413_data $res_td2_h $res_td2_l "$EMC1413_Channel1_name"
convert_emc1413_data $res_td3_h $res_td3_l "$EMC1413_Channel2_name"
}
process_emc1413(){
# emc1413 no need to init
# get chip emc1413 value
read_emc1413_channel_value
}
# ---------------------------------------------------------
# Chip ADC128
# ---------------------------------------------------------
# adc128 chip init if need
check_adc128_init(){
# Get Reg 0x00 status
res_adc128_status=`i2cget -y $i2c_bus $chip_slave $REG_adc128_config`
format_log_print $INFO "REG adc128 STATUS : $res_adc128_status"
# if stauts is not 0x01 (Start Monitor) ,then do init
if [ "$res_adc128_status" != "0x01" ];then
format_log_print $INFO "Start Init ADC128 Chip"
# Init ADC128 work as mode 1 (0x02)
res_adc128_advance=`i2ctransfer -y $i2c_bus w2@$chip_slave $REG_adc128_advance 0x02`
# Set ADC128 on start (0x01)
res_adc128_setstart=`i2ctransfer -y $i2c_bus w2@$chip_slave $REG_adc128_config 0x01 r1`
format_log_print $INFO "After Set status, the REG 0x00 value is $res_adc128_setstart"
fi
}
# process sensor data then print to console
# @Param 1 adc128 data high 8bit
# @Param 2 adc128 data low 8bit
# @Param 3 customization channel name
# @Param 4 division factor
convert_adc128_data(){
# remove data prefix '0x'
hex_value1=$(echo "$1" | awk '{sub(/^0x/,""); print}')
hex_value2=$(echo "$2" | awk '{sub(/^0x/,""); print}')
merge_value="${hex_value1}${hex_value2}"
# bc calculator recognized upper case only, change data to upper case
upper_hex_value=$(echo "$merge_value" | awk '{
for(i=1; i<=length($0); i++){
if(tolower(substr($0,i,1)) ~ /^[a-f]$/)
printf toupper(substr($0,i,1));
else
printf substr($0,i,1);
}
print ""
}')
# calculate dec value then print it to console
dec_val=$(echo "ibase=16; $upper_hex_value" | bc)
volt=$(echo "scale=4; $dec_val / 16 / 4096 * 2.65 / $4" | bc)
format_volt=$(echo "$volt" | awk '{ if ($0 ~ /^\./) print "0" $0; else print $0 }')
echo "$3 : $format_volt v, hex value: $upper_hex_value"
}
# Get the sensor data, then parse raw data
read_adc128_channel_value(){
format_log_print $INFO "Start Read ADC128 channel data ..."
res_ch0=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_adc128_ch0 r2`
res_ch1=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_adc128_ch1 r2`
res_ch2=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_adc128_ch2 r2`
res_ch3=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_adc128_ch3 r2`
res_ch4=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_adc128_ch4 r2`
res_ch5=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_adc128_ch5 r2`
res_ch6=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_adc128_ch6 r2`
res_ch7=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_adc128_ch7 r2`
# record i2c raw data to log
format_log_print $INFO "channel0 : $res_ch0"
format_log_print $INFO "channel1 : $res_ch1"
format_log_print $INFO "channel2 : $res_ch2"
format_log_print $INFO "channel3 : $res_ch3"
format_log_print $INFO "channel4 : $res_ch4"
format_log_print $INFO "channel5 : $res_ch5"
format_log_print $INFO "channel6 : $res_ch6"
format_log_print $INFO "channel7 : $res_ch7"
# start parse raw data
echo ">>> The ADC128 value is :"
convert_adc128_data $res_ch0 "$ADC128_Channel0_name" $votage_division_factor_0
convert_adc128_data $res_ch1 "$ADC128_Channel1_name" $votage_division_factor_1
convert_adc128_data $res_ch2 "$ADC128_Channel2_name" $votage_division_factor_2
convert_adc128_data $res_ch3 "$ADC128_Channel3_name" $votage_division_factor_3
convert_adc128_data $res_ch4 "$ADC128_Channel4_name" $votage_division_factor_4
convert_adc128_data $res_ch5 "$ADC128_Channel5_name" $votage_division_factor_5
convert_adc128_data $res_ch6 "$ADC128_Channel6_name" $votage_division_factor_6
convert_adc128_data $res_ch7 "$ADC128_Channel7_name" $votage_division_factor_7
}
process_adc128(){
# check if chip adc128 need init
check_adc128_init
# get chip adc128 value
read_adc128_channel_value
}
# ---------------------------------------------------------
# Chip INA3221
# ---------------------------------------------------------
# process sensor data then print to console
# @Param1 ina3221 data high 8bit
# @Param2 ina3221 data high 8bit
# @Param3 channel number
# @Param4 mode select 0 - shunt volt
# 1 - bus volt
# @Param5 shunt resistor(only used in mode shunt volt)
# @Param6 customization channel name
convert_ina3221_data(){
hex_value1=$(echo "$1" | awk '{sub(/^0x/,""); print}')
hex_value2=$(echo "$2" | awk '{sub(/^0x/,""); print}')
merge_value="${hex_value1}${hex_value2}"
# bc calculator recognized upper case only, change data to upper case
upper_hex_value=$(echo "$merge_value" | awk '{
for(i=1; i<=length($0); i++){
if(tolower(substr($0,i,1)) ~ /^[a-f]$/)
printf toupper(substr($0,i,1));
else
printf substr($0,i,1);
}
print ""
}')
# change data from hex to dec
dec_val=$(echo "ibase=16; $upper_hex_value" | bc)
if [ $4 -eq $INA3221_BUS_VOLT ];then
volt=$(echo "scale=4; $dec_val / 8 * 40 / 10000 * 2" | bc)
format_volt=$(echo "$volt" | awk '{ if ($0 ~ /^\./) print "0" $0; else print $0 }')
echo "$6 : $format_volt V, hex value: $upper_hex_value"
if [ $3 -eq 0 ];then
ina3221_ch0_volt=$format_volt
elif [ $3 -eq 1 ];then
ina3221_ch1_volt=$format_volt
else
ina3221_ch2_volt=$format_volt
fi
elif [ $4 -eq $INA3221_SHUNT_VOLT ];then
current_mv=$(echo "scale=4; $dec_val / 8 * 40 / 1000" | bc)
current=$(echo "scale=4; $current_mv / $5" | bc)
format_current=$(echo "$current" | awk '{ if ($0 ~ /^\./) print "0" $0; else print $0 }')
format_current_mv=$(echo "$current_mv" | awk '{ if ($0 ~ /^\./) print "0" $0; else print $0 }')
echo "$6 : $format_current A, shunt volt: $format_current_mv mV, shunt resistor: $5 mOhm, hex value: $upper_hex_value"
if [ $3 -eq 0 ];then
ina3221_ch0_current=$format_current
elif [ $3 -eq 1 ];then
ina3221_ch1_current=$format_current
else
ina3221_ch2_current=$format_current
fi
elif [ $4 -eq $INA3221_POWER ];then
# calculate power
power_ch0=$(echo "scale=4; $ina3221_ch0_volt * $ina3221_ch0_current" | bc)
power_ch1=$(echo "scale=4; $ina3221_ch1_volt * $ina3221_ch1_current" | bc)
power_ch2=$(echo "scale=4; $ina3221_ch2_volt * $ina3221_ch2_current" | bc)
format_power_ch0=$(echo "$power_ch0" | awk '{ if ($0 ~ /^\./) print "0" $0; else print $0 }')
format_power_ch1=$(echo "$power_ch1" | awk '{ if ($0 ~ /^\./) print "0" $0; else print $0 }')
format_power_ch2=$(echo "$power_ch2" | awk '{ if ($0 ~ /^\./) print "0" $0; else print $0 }')
total_power=$(echo "scale=4; $power_ch0 + $power_ch1 + $power_ch2" | bc)
echo "$INA3221_Channel0_name : $format_power_ch0 W"
echo "$INA3221_Channel1_name : $format_power_ch1 W"
echo "$INA3221_Channel2_name : $format_power_ch2 W"
echo "total power: $total_power W"
fi
}
# Get the sensor data, then parse raw data
read_ina3221_channel_value(){
format_log_print $INFO "Start Read INA3221 channel data ..."
res_ch0=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_ina3221_ch1 r2`
res_ch1=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_ina3221_ch2 r2`
res_ch2=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_ina3221_ch3 r2`
res_bus0=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_ina3221_bus1 r2`
res_bus1=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_ina3221_bus2 r2`
res_bus2=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_ina3221_bus3 r2`
# record i2c raw data to log
format_log_print $INFO "channel 0 shunt volt: $res_ch0"
format_log_print $INFO "channel 1 shunt volt: $res_ch1"
format_log_print $INFO "channel 2 shunt volt: $res_ch2"
format_log_print $INFO "Channel 0 bus volt : $res_bus0"
format_log_print $INFO "Channel 1 bus volt : $res_bus1"
format_log_print $INFO "Channel 2 bus volt : $res_bus2"
# start parse raw data
echo ">>> The INA3221 shunt value is :"
convert_ina3221_data $res_ch0 0 $INA3221_SHUNT_VOLT $shunt_resistor_0 "$INA3221_Channel0_name"
convert_ina3221_data $res_ch1 1 $INA3221_SHUNT_VOLT $shunt_resistor_1 "$INA3221_Channel1_name"
convert_ina3221_data $res_ch2 2 $INA3221_SHUNT_VOLT $shunt_resistor_2 "$INA3221_Channel2_name"
echo ">>> The INA3221 bus value is :"
convert_ina3221_data $res_bus0 0 $INA3221_BUS_VOLT null "$INA3221_Channel0_name"
convert_ina3221_data $res_bus1 1 $INA3221_BUS_VOLT null "$INA3221_Channel1_name"
convert_ina3221_data $res_bus2 2 $INA3221_BUS_VOLT null "$INA3221_Channel2_name"
echo ">>> The INA3221 bus power is :"
convert_ina3221_data 0 0 0 $INA3221_POWER
}
process_ina3221(){
# ina3221 no need to init first
# get chip ina3221 value
read_ina3221_channel_value
}
# ---------------------------------------------------------
# Chip TMP468
# ---------------------------------------------------------
# @Param1 tmp468 data high 8bit
# @Param2 tmp468 data high 8bit
# @Param3 customization channel name
convert_tmp468_data(){
hex_value1=$(echo "$1" | awk '{sub(/^0x/,""); print}')
hex_value2=$(echo "$2" | awk '{sub(/^0x/,""); print}')
merge_value="${hex_value1}${hex_value2}"
# bc calculator recognized upper case only, change data to upper case
upper_hex_value=$(echo "$merge_value" | awk '{
for(i=1; i<=length($0); i++){
if(tolower(substr($0,i,1)) ~ /^[a-f]$/)
printf toupper(substr($0,i,1));
else
printf substr($0,i,1);
}
print ""
}')
# change data from hex to dec
dec_val=$(echo "ibase=16; $upper_hex_value" | bc)
temp=$(echo "scale=4; $dec_val / 8 * 0.0625" | bc)
echo "$3 : $temp "
}
read_tmp468_value(){
format_log_print $INFO "Start Read tmp468 channel data ..."
res_tmp468=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_tmp468 r18`
format_log_print $INFO "Tmp468 raw data: $res_tmp468"
tmp468_res1_h=`echo $res_tmp468 | awk '{print $1}'`
tmp468_res1_l=`echo $res_tmp468 | awk '{print $2}'`
tmp468_res2_h=`echo $res_tmp468 | awk '{print $3}'`
tmp468_res2_l=`echo $res_tmp468 | awk '{print $4}'`
tmp468_res3_h=`echo $res_tmp468 | awk '{print $5}'`
tmp468_res3_l=`echo $res_tmp468 | awk '{print $6}'`
tmp468_res4_h=`echo $res_tmp468 | awk '{print $7}'`
tmp468_res4_l=`echo $res_tmp468 | awk '{print $8}'`
tmp468_res5_h=`echo $res_tmp468 | awk '{print $9}'`
tmp468_res5_l=`echo $res_tmp468 | awk '{print $10}'`
tmp468_res6_h=`echo $res_tmp468 | awk '{print $11}'`
tmp468_res6_l=`echo $res_tmp468 | awk '{print $12}'`
tmp468_res7_h=`echo $res_tmp468 | awk '{print $13}'`
tmp468_res7_l=`echo $res_tmp468 | awk '{print $14}'`
tmp468_res8_h=`echo $res_tmp468 | awk '{print $15}'`
tmp468_res8_l=`echo $res_tmp468 | awk '{print $16}'`
tmp468_res9_h=`echo $res_tmp468 | awk '{print $17}'`
tmp468_res9_l=`echo $res_tmp468 | awk '{print $18}'`
format_print $INFO "Tmp468 read result:"
convert_tmp468_data $tmp468_res1_h $tmp468_res1_l "$TMP468_Channel0_name"
convert_tmp468_data $tmp468_res2_h $tmp468_res2_l "$TMP468_Channel1_name"
convert_tmp468_data $tmp468_res3_h $tmp468_res3_l "$TMP468_Channel2_name"
convert_tmp468_data $tmp468_res4_h $tmp468_res4_l "$TMP468_Channel3_name"
convert_tmp468_data $tmp468_res5_h $tmp468_res5_l "$TMP468_Channel4_name"
convert_tmp468_data $tmp468_res6_h $tmp468_res6_l "$TMP468_Channel5_name"
convert_tmp468_data $tmp468_res7_h $tmp468_res7_l "$TMP468_Channel6_name"
convert_tmp468_data $tmp468_res8_h $tmp468_res8_l "$TMP468_Channel7_name"
convert_tmp468_data $tmp468_res9_h $tmp468_res9_l "$TMP468_Channel8_name"
}
process_tmp468(){
# tmp112 no need to init firsts
# get chip tmp112 value
read_tmp468_value
}
# ---------------------------------------------------------
# Chip TMP112
# ---------------------------------------------------------
# @Param1 tmp112 data high 8bit
# @Param2 tmp112 data low 8bit
# @Param3 customization sensor name
convert_tmp112_data(){
hex_value1=$(echo "$1" | awk '{sub(/^0x/,""); print}')
hex_value2=$(echo "$2" | awk '{sub(/^0x/,""); print}')
merge_value="${hex_value1}${hex_value2}"
# bc calculator recognized upper case only, change data to upper case
upper_hex_value=$(echo "$merge_value" | awk '{
for(i=1; i<=length($0); i++){
if(tolower(substr($0,i,1)) ~ /^[a-f]$/)
printf toupper(substr($0,i,1));
else
printf substr($0,i,1);
}
print ""
}')
# change data from hex to dec
dec_val=$(echo "ibase=16; $upper_hex_value" | bc)
binary_number=$(echo "ibase=16;obase=2;$upper_hex_value" | bc)
bin_length=$(echo $binary_number | awk '{print length($0)}')
last_digit=$(echo $binary_number | cut -c $bin_length)
if [ $last_digit -eq 0 ];then
temp=$(echo "scale=4; $dec_val / 16 * 0.0625" | bc)
elif [ $last_digit -eq 1 ];then
temp=$(echo "scale=4; ( $dec_val - 1 ) / 8 * 0.0625" | bc)
fi
echo "$3 : $temp"
format_log_print $INFO "dec_val : $dec_val"
format_log_print $INFO "binary_number : $binary_number"
format_log_print $INFO "last_digit : $last_digit"
format_log_print $INFO "temp : $temp"
}
read_tmp112_value(){
format_log_print $INFO "Start Read tmp112 channel data ..."
res_tmp112=`i2ctransfer -y $i2c_bus w1@$chip_slave $REG_tmp112 r2`
format_log_print $INFO "Tmp112 raw data: $res_tmp112"
format_print $INFO "Tmp112 read result:"
convert_tmp112_data $res_tmp112 "$TMP112_Sensor_name"
}
process_tmp112(){
# tmp112 no need to init firsts
# get chip tmp112 value
read_tmp112_value
}
# ---------------------------------------------------------
# CHIP
# ---------------------------------------------------------
# do a customization command
write_read_chip(){
# Modify i2c cmd which write to cpld if need
cmd_wr=$option_data
res_wr=`$cmd_wr`
format_print $INFO "Chip Command: $cmd_wr"
format_print $INFO "The Result : $res_wr"
}
process_chip(){
# cpld no need to init first
# write and read cpld
write_read_chip
}
# ---------------------------------------------------------
# FRU
# ---------------------------------------------------------
# parse fru file to hex string which can be used in i2ctransfer
parse_fru_write_data(){
if [ -e $fru_file_name ];then
format_log_print $INFO "Fru file exist!"
else
format_log_print $ERROR "Fru file not exist!"
format_print $WARNING "Fru file not exist in current directory!"
format_print $ERROR "Operation Failed!"
exit 1
fi
# calculate fru size
fru_write_size=`ls -lht | grep $fru_file_name | awk '{print $5}'`
format_print $INFO "Fru File [$fru_file_name] size = $fru_write_size Bytes"
format_log_print $INFO "Fru File [$fru_file_name] size = $fru_write_size Bytes"
# get fru raw data
fru_raw_data=`hexdump -C $fru_file_name | awk '{
for(i=2;i<18;i++){
print $i
}
}'`
format_log_print $INFO "Fru Raw Data: $fru_raw_data"
# parse data to hex string
fru_write_data=`echo $fru_raw_data | awk -v size=$fru_write_size '{
for(i=1;i<=size;i++){
printf "0x%s ",$i
}
}'`
}
read_fru(){
res_fru=`i2ctransfer -y $i2c_bus w2@$chip_slave $fru_offset r256`
# print fru data every 16 bytes per row
format_print $INFO "The Fru Data :"
echo "$res_fru" | \
awk '{
line="";
count=0;
for(i=1; i<=NF; i++){
hex=substr($i, 3);
if(line != ""){
line = line " ";
}
line = line hex;
count++;
if (count == 16){
print line;
line = "";
count = 0;
}
}
if(line != ""){
print line;
}
}'
}
# !!! untest function !!!
write_fru(){
i2c_write_byte=$(($fru_write_size+2))
write_command="i2ctransfer -y $i2c_bus w$i2c_write_byte@$chip_slave $fru_offset $fru_write_data"
write_res=`$write_command`
format_log_print $INFO "Exec Command: $write_command"
}
process_fru(){
# fru no need to init first
# write and read fru
if [ "$option_data" == "write" ];then
write_fru
else
# default action is read
read_fru
fi
}
# ---------------------------------------------------------
# END of CHIP Function
# ---------------------------------------------------------
start_get_sensor(){
# switch pca9641 and pca9548
# if enable debug mode, will not do this action.
if [ $DEBUG_MODE -eq 0 ];then
# set global varible by server type
set_configuration
record_config_info
# if we have 9641 on i2c, then do it
if [ $is_have_pca9641 -eq 1 ];then
get_pca9641_control
fi
switch_pca9548_channel
fi
# get sensor detail value
case $sensor_type in
"emc1413")
process_emc1413
;;
"adc128")
process_adc128
;;
"ina3221")
process_ina3221
;;
"tmp468")
process_tmp468
;;
"tmp112")
process_tmp112
;;
"chip")
process_chip
;;
"fru")
process_fru
;;
*)
format_print $ERROR "Unsupport Sensor Type !!! - $sensor_type"
format_print $INFO "Support list: $Support_Sensor_List"
print_usage
;;
esac
}
detect_on_5280m7(){
if [ $nic_type == "ocp" ];then
i2c_bus=3
do_i2c_detect 3 0x70 0x01 0 0
do_i2c_detect 3 0x70 0x02 1 1
do_i2c_detect 3 0x70 0x04 2 2
else
i2c_bus=12
pca9641_slave="0x41"
get_pca9641_control
do_i2c_detect 12 0x72 0x02 1 0
do_i2c_detect 12 0x72 0x04 2 1
do_i2c_detect 12 0x72 0x08 3 2
i2c_bus=13
pca9641_slave="0x42"
get_pca9641_control
do_i2c_detect 13 0x72 0x02 1 3
do_i2c_detect 13 0x72 0x04 2 4
do_i2c_detect 13 0x72 0x08 3 5
fi
}
detect_on_5468m7(){
i2c_bus=13
pca9641_slave="0x31"
get_pca9641_control
do_i2c_detect 13 0x70 0x01 0 0
do_i2c_detect 13 0x70 0x02 1 1
do_i2c_detect 13 0x70 0x04 2 2
do_i2c_detect 13 0x70 0x08 3 3
do_i2c_detect 13 0x70 0x10 4 4
i2c_bus=14
pca9641_slave="0x42"
get_pca9641_control
do_i2c_detect 14 0x71 0x01 0 5
do_i2c_detect 14 0x71 0x02 1 6
do_i2c_detect 14 0x71 0x04 2 7
do_i2c_detect 14 0x71 0x08 3 8
do_i2c_detect 14 0x71 0x10 4 9
do_i2c_detect 14 0x71 0x20 5 10
}
detect_on_donghu(){
i2c_bus=3
do_i2c_detect 3 0x70 0x80 7 0
do_i2c_detect 3 0x70 0x40 6 1
do_i2c_detect 3 0x70 0x20 5 2
do_i2c_detect 3 0x70 0x10 4 3
do_i2c_detect 3 0x70 0x08 3 4
do_i2c_detect 3 0x70 0x04 2 5
do_i2c_detect 3 0x70 0x02 1 6
do_i2c_detect 3 0x70 0x01 0 7
}
detect_on_yichun(){
i2c_bus=12
do_i2c_detect 12 0x74 0x02 2 0
i2c_bus=13
do_i2c_detect 13 0x74 0x02 2 1
i2c_bus=14
do_i2c_detect 14 0x74 0x02 2 2
}
detect_on_qiandaohu(){
i2c_bus=3
do_i2c_detect 3 0x70 0x08 3 0
do_i2c_detect 3 0x70 0x04 2 1
do_i2c_detect 3 0x70 0x01 0 2
do_i2c_detect 3 0x70 0x02 1 3
do_i2c_detect 3 0x70 0x80 7 4
do_i2c_detect 3 0x70 0x40 6 5
do_i2c_detect 3 0x70 0x10 4 6
do_i2c_detect 3 0x70 0x20 5 7
i2c_bus=6
do_i2c_detect 6 0x71 0x08 3 8
do_i2c_detect 6 0x71 0x04 2 9
do_i2c_detect 6 0x71 0x01 0 10
do_i2c_detect 6 0x71 0x08 3 11
}
debug_user_defined_detect(){
format_print $INFO "Detect by user-defined"
# default execute
format_print $INFO "Default detect on the current i2c"
i2cdetect -y $i2c_bus
}
start_detect_device(){
# In debug mode, do customization detect action
if [ $DEBUG_MODE -ne 0 ];then
format_print $INFO "In debug mode now"
debug_user_defined_detect
exit 0
fi
format_print $INFO "Detect on server : $server_type, nic type: $nic_type"
case $server_type in
"5280m7")
detect_on_5280m7
;;
"5468m7")
detect_on_5468m7
;;
"donghu")
detect_on_donghu
;;
"yichun")
detect_on_yichun
;;
"qiandaohu")
detect_on_qiandaohu
;;
*)
format_print $ERROR "Unsupport Server Type - $server_type"
format_print $INFO "Support list : $Support_Server_List"
;;
esac
}
# ---------------------------------------------------------
# Start Execute Script
# ---------------------------------------------------------
conf_pre_check
# is param legel?
if [ "$sensor_type" == "chip" ];then
if [ $# -le 3 ];then
format_print $ERROR "Command Format illegal"
print_chip_command_format
exit 1
fi
fi
if [ "$1" == "detect" ];then
if [ "$2" == "ocp" ];then
nic_type="ocp"
elif [ "$2" == "pcie" ];then
nic_type="pcie"
else
format_print $WARNING "Please provide valid nic type, default to pcie"
nic_type="pcie"
fi
start_detect_device
exit 0
fi
init_debuglog
# if the action is fru write, need pre-process fru data
if [ "$sensor_type" == "fru" ];then
if [ "$option_data" == "write" ];then
format_log_print $INFO "Opreation FRU Write"
# is option_data(fru file name) valid?
if [ "$option_data2" == "" ];then
format_print $ERROR "Please provide fru file name"
print_fru_command_format
exit 1
fi
parse_fru_write_data
fi
fi
if [ $# -le 2 ];then
print_usage
else
start_get_sensor
fi