不合理的地方欢迎批评指正!!!
源代码链接:Ultra96-PYNQ_A-simple-summary
1 监控电源状态
PYNQ提供了很方便的工具可以查看电源轨的状态
from pynq import pmbus
rails = pmbus.get_rails()
rails
{'in1': Rail {name=in1, voltage=Sensor {name=in1_voltage, value=1.195V}},
'in10': Rail {name=in10, voltage=Sensor {name=in10_voltage, value=1.798V}},
'in11': Rail {name=in11, voltage=Sensor {name=in11_voltage, value=1.098V}},
'in2': Rail {name=in2, voltage=Sensor {name=in2_voltage, value=1.796V}},
'in3': Rail {name=in3, voltage=Sensor {name=in3_voltage, value=0.845V}},
'in4': Rail {name=in4, voltage=Sensor {name=in4_voltage, value=0.845V}},
'in5': Rail {name=in5, voltage=Sensor {name=in5_voltage, value=1.793V}},
'in6': Rail {name=in6, voltage=Sensor {name=in6_voltage, value=1.795V}},
'in7': Rail {name=in7, voltage=Sensor {name=in7_voltage, value=0.841V}},
'in8': Rail {name=in8, voltage=Sensor {name=in8_voltage, value=0.841V}},
'in9': Rail {name=in9, voltage=Sensor {name=in9_voltage, value=0.841V}}}
但是没法修改…,仅仅是监控。
2 查看PCB的IRPS5401
首先PS的I2C通过一个hub扩展了I2C口的数目,其中SC4、SD4是我们使用的接口
在sysfs中对应i2c-6
xilinx@pynq:~$ cd /sys/class/i2c-
i2c-adapter/ i2c-dev/
xilinx@pynq:~$ cd /sys/class/i2c-dev/
xilinx@pynq:/sys/class/i2c-dev$ tree
.
├── i2c-0 -> ../../devices/platform/amba/ff030000.i2c/i2c-0/i2c-dev/i2c-0
├── i2c-1 -> ../../devices/platform/amba/fd4a0000.zynqmp-display/i2c-1/i2c-dev/i2c-1
├── i2c-2 -> ../../devices/platform/amba/ff030000.i2c/i2c-0/i2c-2/i2c-dev/i2c-2
├── i2c-3 -> ../../devices/platform/amba/ff030000.i2c/i2c-0/i2c-3/i2c-dev/i2c-3
├── i2c-4 -> ../../devices/platform/amba/ff030000.i2c/i2c-0/i2c-4/i2c-dev/i2c-4
├── i2c-5 -> ../../devices/platform/amba/ff030000.i2c/i2c-0/i2c-5/i2c-dev/i2c-5
├── i2c-6 -> ../../devices/platform/amba/ff030000.i2c/i2c-0/i2c-6/i2c-dev/i2c-6
├── i2c-7 -> ../../devices/platform/amba/ff030000.i2c/i2c-0/i2c-7/i2c-dev/i2c-7
├── i2c-8 -> ../../devices/platform/amba/ff030000.i2c/i2c-0/i2c-8/i2c-dev/i2c-8
└── i2c-9 -> ../../devices/platform/amba/ff030000.i2c/i2c-0/i2c-9/i2c-dev/i2c-9
所有的PMIC芯片均挂载在i2c-6
在设备树中查看相应的PMIC信息,可以发现设备树与真实的器件并不对应…,设备树中挂载的设备为ti,tps65086。
xilinx@pynq:~$ cd /sys/firmware/devicetree/base/a
aliases/ amba/ amba_apu@0/ aux_ref_clk/
xilinx@pynq:~$ cd /sys/firmware/devicetree/base/amba/
ahci@fd0c0000/ dma@fd530000/ dma@ffac0000/ gpio@ff0a0000/ pcie@fd0e0000/ spi@ff050000/ watchdog@ff150000/
ams@ffa50000/ dma@fd540000/ dma@ffad0000/ gpu@fd4b0000/ perf-monitor@fd0b0000/ spi@ff0f0000/ zynqmp-display@fd4a0000/
can@ff060000/ dma@fd550000/ dma@ffae0000/ i2c@ff020000/ perf-monitor@fd490000/ timer@ff110000/ zynqmp_phy@fd400000/
can@ff070000/ dma@fd560000/ dma@ffaf0000/ i2c@ff030000/ perf-monitor@ffa00000/ timer@ff120000/ zyxclmm_drm/
cci@fd6e0000/ dma@fd570000/ ethernet@ff0b0000/ memory-controller@fd070000/ perf-monitor@ffa10000/ timer@ff130000/
dma@fd4c0000/ dma@ffa80000/ ethernet@ff0c0000/ memory-controller@ff960000/ rtc@ffa60000/ timer@ff140000/
dma@fd500000/ dma@ffa90000/ ethernet@ff0d0000/ mmc@ff160000/ serial@ff000000/ usb0@ff9d0000/
dma@fd510000/ dma@ffaa0000/ ethernet@ff0e0000/ mmc@ff170000/ serial@ff010000/ usb1@ff9e0000/
dma@fd520000/ dma@ffab0000/ fabric@A0000000/ nand@ff100000/ spi@ff040000/ watchdog@fd4d0000/
xilinx@pynq:~$ cd /sys/firmware/devicetree/base/amba/i2c@ff030000/i2c-mux@75/i2c@
i2c@0/ i2c@1/ i2c@2/ i2c@3/ i2c@4/ i2c@5/ i2c@6/ i2c@7/
xilinx@pynq:~$ cd /sys/firmware/devicetree/base/amba/i2c@ff030000/i2c-mux@75/i2c@4/pmic@5e/
xilinx@pynq:/sys/firmware/devicetree/base/amba/i2c@ff030000/i2c-mux@75/i2c@4/pmic@5e$ cat name
pmicxilinx@pynq:/sys/firmware/devicetree/base/amba/i2c@ff030000/i2c-mux@75/i2c@4/pmic@5e$ tree
.
├── compatible
├── #gpio-cells
├── gpio-controller
├── interrupt-parent
├── interrupts
├── name
├── phandle
└── reg
0 directories, 8 files
xilinx@pynq:/sys/firmware/devicetree/base/amba/i2c@ff030000/i2c-mux@75/i2c@4/pmic@5e$ cat compatible
ti,tps65086xilinx@pynq:/sys/firmware/devicetree/base/amba/i2c@ff030000/i2c-mux@75/i2c@4/pmic@5e$
从这个patch[3/3] hwmon: (pmbus) add support for Infineon IRPS5401发现2019年6月Linux内核才支持IRPS5401,自认为驱动工程师偷懒,没有合并最新的驱动到内核中,所以用已有的ti,tps65086驱动暂且代替。
如果内核中有IRPS5401的驱动,那么就没有下面的骚操作了,可以简单地通过sysfs修改电源轨,具体方法可参阅下面这篇博文。
linux PMBus总线及设备驱动分析
3 修改IRPS5401的电源轨
3.1 想好了再进行
如果没有需求,千万不要修改PMIC,很容易造成板子重启烧坏,因为Ultra96-V2在简化设计中,复用了相应的电源轨。我为了修改PL部分的Bank65,只能忍痛割爱把USB3.0hub芯片用热风枪拆了…
如果没有需求,千万不要修改PMIC。
如果没有需求,千万不要修改PMIC。
USB5744-I/2G这款IC,仅耐受1.2V,如果将电源轨直接修改到1.8V,将会造成芯片损坏。
3.2 硬件解决方案
可以购买USB-to-I2C dongle,然后用官方配套的软件PowIRCenter Software进行解决,方便又省事。
3.3 软件解决方案
直接通过i2c-6修改读取相应的寄存器
3.3.1 支持的PMBus commands
看到那么多寄存器是不是头大,经过阅读,我发现需要修改的寄存器并不多。有钱的话,还是尽量使用USB-to-I2C dongle,省的受罪。
需要修改读取的寄存器如下
PAGE = 0x00
VOUT_MAX = 0x24
VOUT_MARGIN_HIGH = 0x25
VOUT_OV_FAULT_LIMIT = 0x40
VOUT_OV_WARN_LIMIT = 0x42
VOUT_COMMAND = 0x21
VOUT_UV_WARN_LIMIT = 0x43
VOUT_UV_FAULT_LIMIT = 0x44
VOUT_MARGIN_LOW = 0x26
POWER_GOOD_OFF = 0x5F
POWER_GOOD_ON = 0x5E
看这个图是不是明白了些,具体我也懒得细说了,可以查阅数据手册。
数值的设置,可以通过阅读参数符合的PMIC电源轨寄存器相应的值,来初始化想要初始化的电源轨的寄存器。
https://www.cnblogs.com/wahaha02/p/6475966.html
3.3.2 一个示例代码
下面是将PMIC#1的CHB通道由1.2V修改到1.8V的代码。
如果没有需求,千万不要修改PMIC。
如果没有需求,千万不要修改PMIC。
如果没有需求,千万不要修改PMIC。
import smbus
i2c_6 = smbus.SMBus(6)
PMIC_ADDR = 0x43
PAGE = 0x00
VOUT_MAX = 0x24
VOUT_MARGIN_HIGH = 0x25
VOUT_OV_FAULT_LIMIT = 0x40
VOUT_OV_WARN_LIMIT = 0x42
VOUT_COMMAND = 0x21
VOUT_UV_WARN_LIMIT = 0x43
VOUT_UV_FAULT_LIMIT = 0x44
VOUT_MARGIN_LOW = 0x26
POWER_GOOD_OFF = 0x5F
POWER_GOOD_ON = 0x5E
PAGE_01 = 0x01
VOUT_MAX_1894V = 0x01E4
VOUT_MARGIN_HIGH_1855V = 0x01DA
VOUT_OV_FAULT_LIMIT_1953V = 0x01F3
VOUT_OV_WARN_LIMIT_1902V = 0x01E6
VOUT_COMMAND_1801V = 0x01CD
VOUT_UV_WARN_LIMIT_1702V = 0x01B3
VOUT_UV_FAULT_LIMIT_1651V = 0x01A6
VOUT_MARGIN_LOW_1753V = 0x01C0
POWER_GOOD_OFF_1603V = 0x019A
POWER_GOOD_ON_1702V = 0x01B3
i2c_6.write_byte_data(PMIC_ADDR, PAGE, PAGE_01)
temp_reg = i2c_6.read_byte_data(PMIC_ADDR, PAGE)
print("Set PAGE 0x%X %s." %(PAGE_01, "successfully"if temp_reg == PAGE_01 else "faulty") )
i2c_6.write_word_data(PMIC_ADDR, VOUT_MAX, VOUT_MAX_1894V)
temp_reg = i2c_6.read_word_data(PMIC_ADDR, VOUT_MAX)
print("Set VOUT_MAX 1.894V %s." %("successfully"if temp_reg == VOUT_MAX_1894V else "faulty") )
i2c_6.write_word_data(PMIC_ADDR, VOUT_MARGIN_HIGH, VOUT_MARGIN_HIGH_1855V)
temp_reg = i2c_6.read_word_data(PMIC_ADDR, VOUT_MARGIN_HIGH)
print("Set VOUT_MARGIN_HIGH 1.855V %s." %("successfully"if temp_reg == VOUT_MARGIN_HIGH_1855V else "faulty") )
i2c_6.write_word_data(PMIC_ADDR, VOUT_OV_FAULT_LIMIT, VOUT_OV_FAULT_LIMIT_1953V)
temp_reg = i2c_6.read_word_data(PMIC_ADDR, VOUT_OV_FAULT_LIMIT)
print("Set VOUT_OV_FAULT_LIMIT 1.953V %s." %("successfully"if temp_reg == VOUT_OV_FAULT_LIMIT_1953V else "faulty") )
i2c_6.write_word_data(PMIC_ADDR, VOUT_OV_WARN_LIMIT, VOUT_OV_WARN_LIMIT_1902V)
temp_reg = i2c_6.read_word_data(PMIC_ADDR, VOUT_OV_WARN_LIMIT)
print("Set VOUT_OV_WARN_LIMIT 1.902V %s." %("successfully"if temp_reg == VOUT_OV_WARN_LIMIT_1902V else "faulty") )
i2c_6.write_word_data(PMIC_ADDR, VOUT_COMMAND, VOUT_COMMAND_1801V)
temp_reg = i2c_6.read_word_data(PMIC_ADDR, VOUT_COMMAND)
print("Set VOUT_COMMAND 1.801V %s." %("successfully"if temp_reg == VOUT_COMMAND_1801V else "faulty") )
i2c_6.write_word_data(PMIC_ADDR, VOUT_UV_WARN_LIMIT, VOUT_UV_WARN_LIMIT_1702V)
temp_reg = i2c_6.read_word_data(PMIC_ADDR, VOUT_UV_WARN_LIMIT)
print("Set VOUT_UV_WARN_LIMIT 1.702V %s." %("successfully"if temp_reg == VOUT_UV_WARN_LIMIT_1702V else "faulty") )
i2c_6.write_word_data(PMIC_ADDR, VOUT_UV_FAULT_LIMIT, VOUT_UV_FAULT_LIMIT_1651V)
temp_reg = i2c_6.read_word_data(PMIC_ADDR, VOUT_UV_FAULT_LIMIT)
print("Set VOUT_UV_FAULT_LIMIT 1.651V %s." %("successfully"if temp_reg == VOUT_UV_FAULT_LIMIT_1651V else "faulty") )
i2c_6.write_word_data(PMIC_ADDR, VOUT_MARGIN_LOW, VOUT_MARGIN_LOW_1753V)
temp_reg = i2c_6.read_word_data(PMIC_ADDR, VOUT_MARGIN_LOW)
print("Set VOUT_MARGIN_LOW 1.753V %s." %("successfully"if temp_reg == VOUT_MARGIN_LOW_1753V else "faulty") )
i2c_6.write_word_data(PMIC_ADDR, POWER_GOOD_OFF, POWER_GOOD_OFF_1603V)
temp_reg = i2c_6.read_word_data(PMIC_ADDR, POWER_GOOD_OFF)
print("Set POWER_GOOD_OFF 1.603V %s." %("successfully"if temp_reg == POWER_GOOD_OFF_1603V else "faulty") )
i2c_6.write_word_data(PMIC_ADDR, POWER_GOOD_ON, POWER_GOOD_ON_1702V)
temp_reg = i2c_6.read_word_data(PMIC_ADDR, POWER_GOOD_ON)
print("Set POWER_GOOD_ON 1.702V %s." %("successfully"if temp_reg == POWER_GOOD_ON_1702V else "faulty") )
原创不易,严禁剽窃!
欢迎大家关注我创建的微信公众号——小白仓库
原创经验资料分享:包含但不仅限于FPGA、ARM、RISC-V、Linux、LabVIEW等软硬件开发,另外分享生活中的趣事以及感悟。目的是建立一个平台记录学习过的知识,并分享出来自认为有用的与感兴趣的道友相互交流进步。
转载:https://blog.csdn.net/qq_35712169/article/details/106253118