PMU配置(RK808)

本文转载自:http://www.javashuo.com/content/p-6398007.html

硬件原理
pmic 电路原理
平台概述
RK808
PWM 介绍
驱动分析
dts
驱动流程
PMIC
PWM
配置相关
menuconfig
修改各路 DCDC 和 LDO
方法一修改dts
方法二运行中动态设置
设置 DCDC 工作模式接口
方法一初始化设置
方法二运行下切换
调试流程与碰到的问题

调试环境
RK3288
Android5.1

硬件原理
pmic 电路原理
电源分为两种:
DCDC:输入输出压差大时,效率高,但是有纹波问题,成本高,所以大压差,大电流时使用。
LDO:输入输出压差大时,效率低,成本低。
为了提高 LDO 的转换效率,系统上会进行相关优化如:
LDO 输出电压为 1.1V,为了提高效率,其输入电压可以从 VCCIO_3.3V 的 DCDC 给出。
所以电路上如果允许尽量将 LDO 接到 DCDC 输出回路,但是要注意上电时序。
DCDC 一般有两种工作模式:
PWM–纹波瞬态响应好,效率低;
PFM:效率高,但是负载能力差。

平台概述
RICO619(5路DCDC)
RK808
ACT8846
各模块需要供电:
ARM 1.0V
GPU 1.0V
DDR 1.2V
VCCIO 3.3V
LOGIC 1.0V(分立 PWM)
Logic 需要动态调压,如果采用分立DCDC(PWM),调节精度、输出电压一致性不能保证。

双电池 ACT8846 + SYR82X
单电池 RK808 或者 RICOH619 + SYR82X

RK808
(本方案采用的 RK808)

在这里插入图片描述

在这里插入图片描述
开机流程:
当有接适配器时。
VDC 电压 升高; VSYS 上电; PMIC 上电并输出。
当只接电池时,按开机键。
PWRON 拉高; PMIC 上电并输出。PMIC 启动,实现 EPROM 中的默认设置,各路上电完成后,发送 reset 信号,芯片上电,系统启动,PMIC 设备挂载,通过I2C 重新配置 PMIC。

PWM 介绍
PWM 即通过占空比设置电压。
计算占空比:
利用 pwm_regulator_set_voltage 将设置的电压转换成占空比
pwm_value = (max - vol)/coefficient/10 //计算占空比,max 及 coefficient 由板级传参
设置占空比:
在rockchip-pwm-regulator.c中pwm_set_rate()
RATE为0时设置PWM为GPIO口输出低,控制LOGIC电压最高(1.4V)。
RATE为100时设置PWM为GPIO口输出高,控制LOGIC电压最低(0.9V)。
RATE在0~100之间:
根据当前PWM的CLK计算高电平和低电平的值,然后写到PWM控制寄存器中即可
其驱动方面需要按特定流程,先将 PWM 控制器 disable 并且 RESET,然后设置,最后 enable。

驱动分析
dts
先看 rk808.dtsi

rk808_dcdc1_reg: regulator@0 {
            reg = <0>;
            regulator-compatible = "rk_dcdc1";      
            regulator-min-microvolt = <700000>;                 //min 和 max 相同时,初始化会设置电压。不一样则表示范围。
            regulator-max-microvolt = <1500000>;
            regulator-initial-mode = <0x2>;                         //工作模式,类别参考手册
            regulator-initial-state = <3>;                              //suspend 模式下的设置
            regulator-state-mem {                                       //休眠模式下的工作模式
                regulator-state-mode = <0x2>;
                regulator-state-disabled;//disabled //休眠下的使能状态
                regulator-state-uv = <900000>;                  //休眠下的电压
            };      
        };

再看 rk3288-tb_8846.dts

/include/ "rk808.dtsi"
&rk808 {
    gpios =<&gpio0 GPIO_A4 GPIO_ACTIVE_HIGH>,<&gpio0 GPIO_B3 GPIO_ACTIVE_LOW>;
    rk808,system-power-controller;
    regulators {        
        rk808_dcdc1_reg: regulator@0{
            regulator-name= "vdd_arm";          //驱动根据这个name 设置 PMU 电压、工作模式、使能。不可重名。
            regulator-always-on;                      //表示常开
            regulator-boot-on;
        };
        ...
};

驱动流程
PMIC
regulator_ops 注册,完成 PMU 驱动与 regulator 之间链接:
kernel/drivers/regulator/
完成 regulator_ops 的注册后,可以使用 regulator 的接口了。(regulator_set_voltage)

PWM
用 PWM 调整外挂 DCDC 电压,注册 PWM 驱动

pwm_regulator {
        compatible = "rockchip_pwm_regulator";
        pwms = <&pwm1 0 2000>;
        rockchip,pwm_id= <1>;
        rockchip,pwm_voltage_map= <925000 950000 975000 1000000 1025000 1050000 1075000 1100000 1125000 1150000 1175000 1200000 1225000 1250000 1275000 1300000 1325000 1350000 1375000 1400000>;
        rockchip,pwm_voltage= <1000000>;
        rockchip,pwm_min_voltage= <925000>;
        rockchip,pwm_max_voltage= <1400000>;
        rockchip,pwm_suspend_voltage= <950000>;
        rockchip,pwm_coefficient= <475>;
        regulators {
            #address-cells = <1>;
            #size-cells = <0>;
            pwm_reg0: regulator@0 {
                regulator-compatible = "pwm_dcdc1";
                regulator-name= "vdd_logic";
                regulator-min-microvolt = <925000>;
                regulator-max-microvolt = <1400000>;
                regulator-always-on;
                regulator-boot-on;
            };
        };
    };

并且打开 PWM 口

&pwm1 {
    status = "okay";
};

配置相关
menuconfig
/rk808
相关的两个宏打开

修改各路 DCDC 和 LDO
方法一,修改dts
通过设置 dts 里面的

regulator-min-microvolt = < 3300000>;
regulator-max-microvolt = <3300000>;
pwm_regulator { rockchip,pwm_voltage= <1000000>; };

来设置默认电压。

方法二,运行中动态设置

struct regulator *dcdc;
    dcdc =regulator_get(NULL, "name");
    regulator_set_voltage(dcdc, min_uv, max_uv);
    regulator_enable(dcdc);
    regulator_put(dcdc);

设置 DCDC 工作模式接口
DCDC 有两种模式(PWM、PFM)。
有一种 Auto 模式会自动调整 PWM、PFM。
所以我们常说的两种模式是 PWM 和 AUTO(PWM+PFM)。
AUTO 模式 效率高、纹波瞬态响应差。
现在一般都 PWM 模式。

方法一,初始化设置

regulator-initial-mode< 0x2 >

方法二,运行下切换

dcdc = regulator_get(NULL, "name");
regulator_set_mode(dcdc, REGULATOR_MODE_STANDBY);
//pwm:REGULATOR_MODE_NORMAL pfm: REGULATOR_MODE_STANDBY
ldo =regulator_get(NULL, "act_ldo1");
regulator_enable(ldo);      //开启 ldo1
//regulator_disable(ldo); //关闭 ldo1

调试流程与碰到的问题
开机打印 PMU 注册失败,提示 i2c 通信失败,或者直接跑飞
1)测试 i2c 的 CLK 和 data 数据线是否被拉低;
2)核对 i2c 有没有注册错,使用的 i2c 是否跟平台上一致;
3)i2c 上是否还有其他设备;
4)测试 PMIC 的各路默认的上电电压是否正确;
5)测试Power_hold 是否为高;
6)测试 PMIC 默认上电完成后 reset 信号是否发送;
7)PMIC 外围部件是
否焊接错误,例如晶振有没有焊反,电感、电容等有没有焊错。
系统运行中死机
1)测试死机时各路的电压,是否有电压异常;
2)测试 DVFS 调整是否正常;
3)测试 arm、logic、DDR、VCCIO 的电压的纹波等,看下在系统异常时是否有明显的电压塌陷。
3 、待机唤醒死机
1)测试 PMU_sleep 脚已经恢复成低;
2)测试各路电压已经从待机电压恢复回来;
3)用示波器测试唤醒时各路电压的的变化波形,有无异常;4)sleep 状态不去关闭电源。不降低电压;
Reset 后无法开机或者某些设备异常
Reset
如果出现此问题,请参考本文第三章 pmic 的关机及复位。
Reset 按下时,芯片复位,各个 io 口恢复成默认值,如果 PMU 没有复位功能或者没有完成硬复位,
则 PMU 不会被复位,则无法完成 PMU 的断电并重新上电,这样可能会导致部分设备重启后工作
不正常。(部分项目上发现有些设备在复位时必须要掉电,否则会工作异常)
RTC 无法正常写入
RTC
1)如果 PMU 是 act8846(不带 RTC)此时要看下 RTC 设备是否挂载正常;2)PMU 设备的 i2c
通信是否正常
运行时部分 LDO 没有输出
1)确认此 LDO 在其他地方没有被关闭,通过搜索此 LDO 的 name (使用此接口 regulator_disable());
2)测试 PMIC_SLEEP 脚是不是为高,如果为高,PMU 已经进入休眠模式,部分 LDO 会被关闭。
PMIC_SLEEP 脚的配置应该是不对的,需要配置此 io 口:见本文档 1.2 章(注意:硬件上此 io 口,
最好没有复用功能,而且是应该是默认内部下拉口)
关机后随机性的自动开机或者关机失败
关机失败:device_shutdown()中会通过 i2c 写关机命令,i2c 通信失败,无法写关机命令。如果遇到此问题。加一些保护锁,如果一直写失败,直接重启。
关机后自动开机:因为 RTC 闹铃具有开机的功能,在关机后如果 RTC 闹铃产生,即会触发开机条
件而开机。目前已经解决过了,在关机函数中先关闭 RTC 闹铃的中断,在开机时再打开中断。
待机时随机性被唤醒
如果唤醒中断是 PMIC_INT,那么应该是 PMU 的 RTC 闹铃在唤醒系统。除了用户设置的闹铃外,
还有一些谷歌的应用会产生 RTC 闹铃,需要移除相应的应用。查看方法如下:
请客户在命令行中敲入 dumpsys alarm 来查看当前系统的 alarm 申请情况。
android 总共有4种类型 alarm,其中只有2种 alarm 会在休眠唤醒系统,请在相关信息中查找对应的
第三方软件。
这两种分别是 ELAPSED_WAKEUP 和 RTC_WAKEUP。
我们观察到,凡是带了谷歌相关的 apk 就会申请相关 alarm,如下:
RTC_WAKEUP #5: Alarm{413418b8 type 0 com.google.android.gsf}
type=0 when=+5d17h1m54s609ms repeatInterval=566316000 count=0
operation=PendingIntent{41294818: PendingIntentRecord{413ce158
com.google.android.gsf broadcastIntent}}
注意:此唤醒动作只在二级待机,不会到一级待机唤醒,点亮屏,如果点亮了屏,应该是屏那边没有进
休眠。
RICOH619
RICOH619
RICOH619无法开机或者开机后电量显示异常
确认电池包上 TS 端是否有10K 电阻,如果没有,请确认板子上 TS 端对地有10K 电阻。如果没有10K
电阻,PMIC 默认电池是不存在的。
RICOH619
RICOH619充电异常,充电电流多小,或者充电充不满
充电电流过小:
我们上电有默认的充电电流,USB:500MA , ADP :1A,开机后 USB 根据枚举结果通过 I2C
重新设置充电电流,最大可设置 3A(一般推荐到 2A),ADP 电流开机后就会修改,最大 3A。
实际往电池充的电流跟设置电流会有一些不一样,有充电效率的关系。详细见下:
ILIM_USB/ILIM_ADP 的设置值 限制 USB/ADP 输入时 VSYS 系统输出的电流极限最大
限流。 ( 实际限制的输出值 大约在 设置值 的 90% 左右 )
因为 工作方式是 DCDC 的关系, 实际的输入电流会小于输出电流。
( 功率转换:理想情况下 输入 5V x 1A
5V = VADP, 1A = I_ADP,
4V = VSYS,
=4V * 1.25A )
Ex.
ILIM_ADP = 1.25A.
另外,限制电流的侦测方式是 由 ILM, ILP 间的 Sense 电阻 压降而得到。
( ILM , ILP 端口需要直接采集 电阻( 20mohm ) 上的 压降,需要注意版图画法)
关于流入电池的电流 可以 查看一下 ICM , ICP 之间的 Sense 电阻的压降来判断。
当然,也需要小心制版时, PMU 的 ICM, ICP 是否取到的直接时 电阻两端的电压。
1.5A 设置 输入限流, 实际输出限制 大约 1.3A 以上。
( 可通过 检测 ILM /
ILP 间 电阻压降 )
由于是 DCDC 工作的方式, IUSB= VSYS * I_SYS V_USB * I_USB * 效率 = VSYS * I_SYS / (V_USB * 效率 ) = 4.0 * 1.3 / ( 5 * 0.9 ) = 1.1A ( 约 ) 充电充不满: 充电有充电时间的限制,一般是充电 5 小时就会关闭充电,所以存在一边使用一边充电时电池充 不满,这个问题我们后期会使用软件解决。

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
对于PMU(Phasor Measurement Unit)的最优配置,可以使用Python进行计算和优化。以下是一个基本的示例代码,用于通过遗传算法找到PMU的最佳位置配置: ```python import numpy as np from scipy.optimize import minimize # 目标函数:最小化PMU位置与目标测量点之间的距离总和 def objective_function(x, target_points): total_distance = 0 num_pmu = len(x) // 2 for i in range(num_pmu): pmu_x, pmu_y = x[i], x[i + num_pmu] for j in range(len(target_points)): target_x, target_y = target_points[j] distance = np.sqrt((pmu_x - target_x) ** 2 + (pmu_y - target_y) ** 2) total_distance += distance return total_distance # 约束条件:PMU位置必须在给定的范围内 def constraint(x, x_range, y_range): num_pmu = len(x) // 2 for i in range(num_pmu): pmu_x, pmu_y = x[i], x[i + num_pmu] if pmu_x < x_range[0] or pmu_x > x_range[1] or pmu_y < y_range[0] or pmu_y > y_range[1]: return False return True # PMU位置配置优化 def optimize_pmu_position(target_points, x_range, y_range): num_pmu = 3 # 设置PMU数量 x0 = np.random.uniform(low=x_range[0], high=x_range[1], size=num_pmu * 2) # 初始配置 bounds = [(x_range[0], x_range[1])] * num_pmu + [(y_range[0], y_range[1])] * num_pmu # 变量的边界 constraint_func = {'type': 'eq', 'fun': constraint, 'args': (x_range, y_range)} # 约束条件 # 使用遗传算法进行优化 result = minimize(objective_function, x0, args=(target_points,), bounds=bounds, constraints=constraint_func) best_pmu_positions = result.x[:num_pmu], result.x[num_pmu:] return best_pmu_positions # 示例输入数据 target_points = [(1, 2), (3, 4), (5, 6), (7, 8)] x_range = (0, 10) y_range = (0, 10) # 运行PMU位置配置优化 best_positions = optimize_pmu_position(target_points, x_range, y_range) print("Best PMU positions:", best_positions) ``` 请注意,这只是一个基本示例,实际应用中可能需要根据具体情况进行调整。此代码使用了Scipy库中的`minimize`函数来执行遗传算法优化,通过最小化PMU位置与目标测量点之间的距离总和来找到最佳配置。同时,通过约束条件确保PMU位置在给定的范围内。 你可以根据实际情况修改和扩展这个示例代码,以满足你的需求。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值