SensorLib 0.5.0
Multi-platform sensor driver library for Arduino, PlatformIO, and ESP-IDF
Loading...
Searching...
No Matches
AXP2101Channel.cpp
Go to the documentation of this file.
1
31#include "../../../SensorBuildOpt.h"
32#if !SENSORLIB_EXCLUDE_PMIC_AXP2101
33
34#include "AXP2101Channel.hpp"
35#include "AXP2101Regs.hpp"
36
38{
39}
40
41bool AXP2101Channel::enable(uint8_t channel, bool enable)
42{
43 if (channel >= CHANNEL_COUNT) return false;
44
45 if (isDCDC(channel)) {
48 }
49
50 uint8_t ldoIdx = channel - DCDC_COUNT;
52 uint8_t bit = (ldoIdx <= 7) ? ldoIdx : 0;
53 return enable ? _core.setRegBit(reg, bit) : _core.clrRegBit(reg, bit);
54}
55
56bool AXP2101Channel::isEnabled(uint8_t channel)
57{
58 if (channel >= CHANNEL_COUNT) return false;
59
60 if (isDCDC(channel)) {
61 return _core.getRegBit(axp2101_regs::dcdc::ONOFF_DVM_CTRL, channel);
62 }
63
64 uint8_t ldoIdx = channel - DCDC_COUNT;
66 uint8_t bit = (ldoIdx <= 7) ? ldoIdx : 0;
67 return _core.getRegBit(reg, bit);
68}
69
70bool AXP2101Channel::setVoltage(uint8_t channel, uint16_t mV)
71{
72 if (channel >= CHANNEL_COUNT) return false;
73
74 static const uint8_t dcdcRegs[] = {
77 };
78 static const uint8_t ldoRegs[] = {
82 };
83
84 if (isDCDC(channel)) {
85 uint8_t reg = dcdcRegs[channel];
86 switch (channel) {
87 case CH_DCDC1: {
88 if (mV < 1500) mV = 1500;
89 if (mV > 3400) mV = 3400;
90 return _core.updateBits(reg, 0x1F, (mV - 1500) / 100) >= 0;
91 }
92 case CH_DCDC2: {
93 if (mV >= 500 && mV <= 1200) {
94 return _core.updateBits(reg, 0x7F, (mV - 500) / 10) >= 0;
95 } else if (mV >= 1220 && mV <= 1540) {
96 return _core.updateBits(reg, 0x7F, (mV - 1220) / 20 + 71) >= 0;
97 }
98 return false;
99 }
100 case CH_DCDC3: {
101 if (mV >= 500 && mV <= 1200) {
102 return _core.updateBits(reg, 0x7F, (mV - 500) / 10) >= 0;
103 } else if (mV >= 1220 && mV <= 1540) {
104 return _core.updateBits(reg, 0x7F, (mV - 1220) / 20 + 71) >= 0;
105 } else if (mV >= 1600 && mV <= 3400) {
106 return _core.updateBits(reg, 0x7F, (mV - 1600) / 100 + 88) >= 0;
107 }
108 return false;
109 }
110 case CH_DCDC4: {
111 if (mV >= 500 && mV <= 1200) {
112 return _core.updateBits(reg, 0x7F, (mV - 500) / 10) >= 0;
113 } else if (mV >= 1220 && mV <= 1840) {
114 return _core.updateBits(reg, 0x7F, (mV - 1220) / 20 + 71) >= 0;
115 }
116 return false;
117 }
118 case CH_DCDC5: {
119 if (mV == 1200) {
120 return _core.updateBits(reg, 0x1F, 0x19) >= 0;
121 }
122 if (mV < 1400) mV = 1400;
123 if (mV > 3700) mV = 3700;
124 return _core.updateBits(reg, 0x1F, (mV - 1400) / 100) >= 0;
125 }
126 }
127 return false;
128 }
129
130 uint8_t ldoIdx = channel - DCDC_COUNT;
131 uint8_t reg = ldoRegs[ldoIdx];
132
133 // ALDO1-4 (ldoIdx 0-3) and BLDO1-2 (ldoIdx 4-5): 500-3500mV, 100mV steps
134 if (ldoIdx <= 5) {
135 if (mV < 500) mV = 500;
136 if (mV > 3500) mV = 3500;
137 return _core.updateBits(reg, 0x1F, (mV - 500) / 100) >= 0;
138 }
139
140 if (ldoIdx == 6) {
141 if (mV < 500) mV = 500;
142 if (mV > 1400) mV = 1400;
143 return _core.updateBits(reg, 0x1F, (mV - 500) / 50) >= 0;
144 }
145
146 if (ldoIdx == 7) { // DLDO1
147 if (mV < 500) mV = 500;
148 if (mV > 3300) mV = 3300;
149 return _core.updateBits(reg, 0x1F, (mV - 500) / 100) >= 0;
150 }
151
152 if (ldoIdx == 8) { // DLDO2: 0.5-1.4V, 50mV steps
153 if (mV < 500) mV = 500;
154 if (mV > 1400) mV = 1400;
155 return _core.updateBits(reg, 0x1F, (mV - 500) / 50) >= 0;
156 }
157
158 return false;
159}
160
161uint16_t AXP2101Channel::getVoltage(uint8_t channel)
162{
163 if (channel >= CHANNEL_COUNT) return 0;
164
165 static const uint8_t dcdcRegs[] = {
168 };
169 static const uint8_t ldoRegs[] = {
173 };
174
175 if (isDCDC(channel)) {
176 int val = _core.readReg(dcdcRegs[channel]);
177 if (val < 0) return 0;
178 val &= 0x7F;
179 switch (channel) {
180 case CH_DCDC1:
181 return (val & 0x1F) * 100 + 1500;
182 case CH_DCDC2:
183 if (val < 71) return val * 10 + 500;
184 return (val - 71) * 20 + 1220;
185 case CH_DCDC3:
186 if (val < 71) return val * 10 + 500;
187 if (val < 88) return (val - 71) * 20 + 1220;
188 return (val - 88) * 100 + 1600;
189 case CH_DCDC4:
190 if (val < 71) return val * 10 + 500;
191 return (val - 71) * 20 + 1220;
192 case CH_DCDC5:
193 val &= 0x1F;
194 if (val == 0x19) return 1200;
195 return val * 100 + 1400;
196 }
197 return 0;
198 }
199
200 uint8_t ldoIdx = channel - DCDC_COUNT;
201 int val = _core.readReg(ldoRegs[ldoIdx]);
202 if (val < 0) return 0;
203 uint8_t code = val & 0x1F;
204
205 if (ldoIdx == 6) {
206 return code * 50 + 500;
207 }
208 if (ldoIdx == 8) {
209 // DLDO2: 500-1400mV, 50mV steps
210 return code * 50 + 500;
211 }
212 return code * 100 + 500;
213}
214
216{
217 return CHANNEL_COUNT;
218}
219
221{
222 static const Info channelInfo[] = {
223 {CH_DCDC1, Type::DCDC, 1500, 3400, 100, "DCDC1"},
224 {CH_DCDC2, Type::DCDC, 500, 1540, 10, "DCDC2"},
225 {CH_DCDC3, Type::DCDC, 500, 3400, 10, "DCDC3"},
226 {CH_DCDC4, Type::DCDC, 500, 1840, 10, "DCDC4"},
227 {CH_DCDC5, Type::DCDC, 1200, 3700, 100, "DCDC5"},
228 {CH_ALDO1, Type::LDO, 500, 3500, 100, "ALDO1"},
229 {CH_ALDO2, Type::LDO, 500, 3500, 100, "ALDO2"},
230 {CH_ALDO3, Type::LDO, 500, 3500, 100, "ALDO3"},
231 {CH_ALDO4, Type::LDO, 500, 3500, 100, "ALDO4"},
232 {CH_BLDO1, Type::LDO, 500, 3500, 100, "BLDO1"},
233 {CH_BLDO2, Type::LDO, 500, 3500, 100, "BLDO2"},
234 {CH_CPUSLDO, Type::LDO, 500, 1400, 50, "CPUSLDO"},
235 {CH_DLDO1, Type::LDO, 500, 3300, 100, "DLDO1"},
236 {CH_DLDO2, Type::LDO, 500, 1400, 50, "DLDO2"},
237 };
238 if (channel >= CHANNEL_COUNT) {
239 return {0, Type::DCDC, 0, 0, 0, "UNKNOWN"};
240 }
241 return channelInfo[channel];
242}
243
244#endif
@license MIT License
static constexpr uint8_t CH_ALDO4
static constexpr uint8_t CH_ALDO1
uint8_t count() const override
Get the total number of available power channels.
Info getInfo(uint8_t channel) const override
Get information about a specific power channel.
static constexpr uint8_t CH_DCDC1
static constexpr uint8_t CH_CPUSLDO
static constexpr uint8_t CH_ALDO3
static constexpr uint8_t CH_DCDC2
static constexpr uint8_t DCDC_COUNT
Number of DCDC converters.
static constexpr uint8_t CH_DCDC5
static constexpr uint8_t CH_ALDO2
AXP2101Channel(AXP2101Core &core)
bool enable(uint8_t channel, bool enable) override
Enable or disable a power output channel.
uint16_t getVoltage(uint8_t channel) override
Get the current output voltage setting for a channel.
static constexpr uint8_t CH_DCDC3
static constexpr uint8_t CH_DLDO2
static constexpr uint8_t CH_BLDO1
static constexpr uint8_t CH_BLDO2
static constexpr uint8_t CH_DCDC4
bool setVoltage(uint8_t channel, uint16_t mV) override
Set the output voltage for a DCDC or LDO channel.
static constexpr uint8_t CH_DLDO1
bool isEnabled(uint8_t channel) override
Check whether a power output channel is enabled.
static constexpr uint8_t CHANNEL_COUNT
Total number of power channels.
Core I2C communication layer for the AXP2101 PMIC.
@ LDO
Linear low-dropout regulator.
@ DCDC
Switching buck/boost converter.
bool clrRegBit(uint8_t reg, uint8_t bit)
bool getRegBit(uint8_t reg, uint8_t bit)
int readReg(uint8_t reg) const
int updateBits(uint8_t reg, uint8_t mask, uint8_t value_shifted)
bool setRegBit(uint8_t reg, uint8_t bit)
Static metadata for a single power output channel.
static constexpr uint8_t VOL0_CTRL
static constexpr uint8_t ONOFF_DVM_CTRL
static constexpr uint8_t VOL3_CTRL
static constexpr uint8_t VOL4_CTRL
static constexpr uint8_t VOL2_CTRL
static constexpr uint8_t VOL1_CTRL
static constexpr uint8_t VOL8_CTRL
static constexpr uint8_t ONOFF_CTRL1
static constexpr uint8_t VOL0_CTRL
static constexpr uint8_t VOL5_CTRL
static constexpr uint8_t VOL7_CTRL
static constexpr uint8_t VOL4_CTRL
static constexpr uint8_t VOL3_CTRL
static constexpr uint8_t VOL2_CTRL
static constexpr uint8_t ONOFF_CTRL0
static constexpr uint8_t VOL6_CTRL
static constexpr uint8_t VOL1_CTRL