SensorLib 0.5.0
Multi-platform sensor driver library for Arduino, PlatformIO, and ESP-IDF
Loading...
Searching...
No Matches
AXP517Adc.cpp
Go to the documentation of this file.
1
30#include "../../../SensorBuildOpt.h"
31#if !SENSORLIB_EXCLUDE_PMIC_AXP517
32
33#include "AXP517Adc.hpp"
34#include "AXP517Regs.hpp"
35
36
37AXP517Adc::AXP517Adc(AXP517Core &core) : _core(core)
38{
39}
40
41static uint8_t axp517_channelToMask(PmicAdcBase::Channel ch)
42{
43 switch (ch) {
44 case PmicAdcBase::Channel::BAT_VOLTAGE: return 0x01;
46 case PmicAdcBase::Channel::VBUS_VOLTAGE: return 0x04;
47 case PmicAdcBase::Channel::VSYS_VOLTAGE: return 0x08;
49 case PmicAdcBase::Channel::BAT_CURRENT: return 0x60; // BAT_CHARGE | BAT_DISCHARGE
50 case PmicAdcBase::Channel::VBUS_CURRENT: return 0x80;
51 default: return 0;
52 }
53}
54
55bool AXP517Adc::enableChannels(uint32_t mask)
56{
57 uint8_t hwMask = 0;
58 forEachChannel(mask, [&](uint32_t bit) {
59 auto ch = static_cast<Channel>(bit);
60 hwMask |= axp517_channelToMask(ch);
61 });
62 if (hwMask == 0) return false;
63 int regVal = _core.readReg(axp517_regs::adc::ENABLE);
64 if (regVal < 0) return false;
65 regVal |= hwMask;
66 return _core.writeReg(axp517_regs::adc::ENABLE, static_cast<uint8_t>(regVal)) == 0;
67}
68
69bool AXP517Adc::disableChannels(uint32_t mask)
70{
71 uint8_t hwMask = 0;
72 forEachChannel(mask, [&](uint32_t bit) {
73 auto ch = static_cast<Channel>(bit);
74 hwMask |= axp517_channelToMask(ch);
75 });
76 if (hwMask == 0) return false;
77 int regVal = _core.readReg(axp517_regs::adc::ENABLE);
78 if (regVal < 0) return false;
79 regVal &= ~hwMask;
80 return _core.writeReg(axp517_regs::adc::ENABLE, static_cast<uint8_t>(regVal)) == 0;
81}
82
83bool AXP517Adc::read(Channel ch, float &out)
84{
85 int16_t adcVal;
86 uint8_t buffer[2] = {0, 0};
87 out = NAN; // Default to NaN for unsupported channels or read errors
88
91
92 if (_core.readRegBuff(axp517_regs::bmu::STATUS0, buffer, sizeof(buffer)) < 0) {
93 return false;
94 }
95 bool vbusPresent = (buffer[0] >> 5) & 0x01;
96 bool batPresent = (buffer[0] >> 3) & 0x01;
97
99 if (!vbusPresent) {
100 // VBUS is not present
101 out = 0.0f;
102 return true;
103 }
104 }
105
106 if (ch == Channel::BAT_VOLTAGE || ch == Channel::BAT_CURRENT) {
107 if (!batPresent) {
108 // Battery is not present
109 out = 0.0f;
110 return true;
111 }
112 }
113 }
114
115 switch (ch) {
117 if (_core.readRegBuff(axp517_regs::adc::VBUS_VOLT_H, buffer, sizeof(buffer)) < 0)
118 return false;
119 out = ((buffer[0] & 0x3F) << 8 | buffer[1]) * axp517_regs::factory::FACTORY_VBUS_VOLTAGE;
120 break;
122 if (_core.readRegBuff(axp517_regs::adc::VBUS_CURR_H, buffer, sizeof(buffer)) < 0)
123 return false;
124 adcVal = (static_cast<int16_t>((buffer[0] & 0x3F) << 8 | buffer[1]));
126 break;
128 if (_core.readRegBuff(axp517_regs::adc::BAT_VOLT_H, buffer, sizeof(buffer)) < 0)
129 return false;
130 out = ((buffer[0] & 0x3F) << 8 | buffer[1]) * axp517_regs::factory::FACTORY_VBAT_VOLTAGE;
131 break;
133 if (_core.readRegBuff(axp517_regs::adc::BAT_CURR_H, buffer, sizeof(buffer)) < 0)
134 return false;
135 adcVal = (static_cast<int16_t>(buffer[0]) << 8) | buffer[1];
136 out = static_cast<float>(adcVal) * axp517_regs::factory::FACTORY_BAT_CURRENT;
137 break;
139 if (_core.writeReg(axp517_regs::adc::DATA_SEL, 0x01) < 0) return false;
140 if (_core.readRegBuff(axp517_regs::adc::DATA_H, buffer, 2) < 0) return false;
141 adcVal = ((buffer[0] & 0x3F) << 8) | buffer[1];
142 out = static_cast<int16_t>((buffer[0] & 0x3F) << 8 | buffer[1]) * axp517_regs::factory::FACTORY_VSYS_VOLTAGE;
143 break;
145 if (_core.writeReg(axp517_regs::adc::DATA_SEL, 0x00) < 0) return false;
146 if (_core.readRegBuff(axp517_regs::adc::DATA_H, buffer, 2) < 0) return false;
147 adcVal = ((buffer[0] & 0x3F) << 8) | buffer[1];
148 out = (3552.0f - adcVal) / 1.79f + 25.0f;
149 break;
151 if (_core.readRegBuff(axp517_regs::gauge::BAT_TEMP, buffer, 1) < 0) {
152 return false;
153 }
154 out = static_cast<float>(buffer[0]);
155 break;
157 if (_core.readRegBuff(axp517_regs::gauge::BAT_PERCENT, buffer, 1) < 0) {
158 return false;
159 }
160 out = static_cast<float>(buffer[0]);
161 break;
162 default:
163 return false;
164 }
165 return true;
166}
167
168#endif
@license MIT License
@license MIT License
AXP517Adc(AXP517Core &core)
Construct an AXP517 ADC driver.
Definition AXP517Adc.cpp:37
bool enableChannels(uint32_t mask) override
Enable one or more ADC channels.
Definition AXP517Adc.cpp:55
bool read(Channel ch, float &out) override
Read an ADC channel.
Definition AXP517Adc.cpp:83
bool disableChannels(uint32_t mask) override
Disable one or more ADC channels.
Definition AXP517Adc.cpp:69
AXP517 low-level core driver.
static void forEachChannel(uint32_t mask, Func fn)
Helper to iterate over set bits in a bitmask.
Channel
ADC channel bitmask.
@ BAT_PERCENTAGE
Battery percentage.
@ DIE_TEMPERATURE
Die temperature.
@ BAT_VOLTAGE
Battery voltage.
@ BAT_TEMPERATURE
Battery temperature.
@ BAT_CURRENT
Battery current.
@ VBUS_CURRENT
VBUS current.
@ VBUS_VOLTAGE
VBUS voltage.
@ VSYS_VOLTAGE
VSYS voltage.
int readReg(uint8_t reg) const
int writeReg(uint8_t reg, uint8_t val)
int readRegBuff(uint8_t reg, uint8_t *buf, size_t len) const
static constexpr uint8_t BAT_VOLT_H
BAT voltage ADC high.
static constexpr uint8_t ENABLE
ADC channel enable control.
static constexpr uint8_t VBUS_CURR_H
VBUS current ADC high.
static constexpr uint8_t BAT_CURR_H
BAT current ADC high.
static constexpr uint8_t DATA_H
ADC data high.
static constexpr uint8_t VBUS_VOLT_H
VBUS voltage ADC high.
static constexpr uint8_t DATA_SEL
ADC data select.
static constexpr uint8_t STATUS0
BMU status0.
static constexpr float FACTORY_BAT_CURRENT
16-Bit(including sign bit)
static constexpr float FACTORY_VBUS_CURRENT
14-Bit(including sign bit)
static constexpr float FACTORY_VBAT_VOLTAGE
14-Bit(including sign bit)
static constexpr float FACTORY_VSYS_VOLTAGE
14-Bit(including sign bit)
static constexpr float FACTORY_VBUS_VOLTAGE
14-Bit(including sign bit)
static constexpr uint8_t BAT_PERCENT
Battery percentage (RO)
static constexpr uint8_t BAT_TEMP
Battery temperature (RO)