30#include "../../../SensorBuildOpt.h"
31#if !SENSORLIB_EXCLUDE_PMIC_AXP517
41static constexpr uint8_t POWER_STATUS_UNINIT = (1u << 6);
42static constexpr uint8_t POWER_STATUS_VBUS_PRESENT = (1u << 2);
44static constexpr uint8_t ROLE_CTRL_SINK_RD_RD = 0x0A;
45static constexpr uint8_t ROLE_CTRL_OPEN_OPEN = 0x0F;
46static constexpr uint8_t ALERT_MASK_IRQ_VALUE = 0x77;
47static constexpr uint8_t POWER_STATUS_MASK_VALUE = 0x04;
48static constexpr uint8_t MSG_HDR_PD20_SINK_UFP = 0x02;
49static constexpr uint8_t RX_DETECT_SOP = 0x01;
50static constexpr uint8_t ADC_VBUS_ENABLE = 0x04;
53bool AXP517Tcpc::r8(uint8_t reg, uint8_t &out)
56 if (v < 0)
return false;
57 out =
static_cast<uint8_t
>(v);
61bool AXP517Tcpc::w8(uint8_t reg, uint8_t v)
66bool AXP517Tcpc::readNoInc(uint8_t reg, uint8_t *
buf, uint8_t len)
74bool AXP517Tcpc::writeNoInc(uint8_t reg,
const uint8_t *
buf, uint8_t len)
76 if (!
buf && len)
return false;
78 for (uint8_t
i = 0;
i < len; ++
i) {
79 if (!w8(reg,
buf[
i]))
return false;
91 if (!w8(CC_GENERAL_CONTROL, SW_RESET))
return false;
93 if (!w8(CC_GENERAL_CONTROL, 0x00))
return false;
96 for (uint8_t
i = 0;
i < 40; ++
i) {
98 if (!r8(POWER_STATUS, status))
return false;
99 if ((status & POWER_STATUS_UNINIT) == 0)
break;
104 if (!r8(POWER_STATUS, status))
return false;
105 if (status & POWER_STATUS_UNINIT)
return false;
107 if (!w8(FAULT_STATUS, 0xFF))
return false;
108 if (!w8(CC_CONNECTION_STATUS, 0xFF))
return false;
110 if (!w8(ROLE_CONTROL, ROLE_CTRL_SINK_RD_RD))
return false;
111 if (!w8(TCPC_CONTROL, 0x00))
return false;
115 if (!w8(TWI_ADDR_STATIC, 0x01))
return false;
118 if (!w8(POWER_STATUS_MASK, POWER_STATUS_MASK_VALUE))
return false;
119 if (!w8(COMMAND, cmd::ENABLE_VBUS_DETECT))
return false;
120 if (!w8(PD_ALERT_MASKL, ALERT_MASK_IRQ_VALUE))
return false;
121 if (!w8(PD_ALERT_MASKH, 0x00))
return false;
123 if (!w8(POWER_CONTROL, 0x10))
return false;
135 if (!w8(ROLE_CONTROL, ROLE_CTRL_OPEN_OPEN))
return false;
137 if (!w8(ROLE_CONTROL, ROLE_CTRL_SINK_RD_RD))
return false;
146 uint8_t lo = 0, hi = 0;
147 if (!r8(TCPC_VENDOR_ID, lo))
return false;
148 if (!r8(TCPC_VENDOR_ID + 1, hi))
return false;
150 uint16_t vid =
static_cast<uint16_t
>(lo) | (
static_cast<uint16_t
>(hi) << 8);
151 return vid == VENDOR_ID || vid == 0xE0C5;
156 uint8_t lo = 0, hi = 0;
157 if (!r8(PD_ALERTL, lo))
return false;
158 if (!r8(PD_ALERTH, hi))
return false;
159 out =
static_cast<uint16_t
>(lo) | (
static_cast<uint16_t
>(hi) << 8);
165 if (!w8(PD_ALERTL,
static_cast<uint8_t
>(maskRw1c & 0xFF)))
return false;
166 return w8(PD_ALERTH,
static_cast<uint8_t
>((maskRw1c >> 8) & 0xFF));
171 return r8(FAULT_STATUS, out);
176 return w8(FAULT_STATUS, maskRw1c);
183 if (!r8(reg, status))
return false;
184 if (status && !w8(reg, status))
return false;
191 return w8(MESSAGE_HEADER_INFO, v);
196 return w8(RECEIVE_DETECT, v);
201 if (!w8(TX_BYTE_CNT, 0x00))
return false;
202 return w8(TX_BUF_TRANSMIT, 0x00);
207 if (!w8(MESSAGE_HEADER_INFO, MSG_HDR_PD20_SINK_UFP))
return false;
208 return w8(RECEIVE_DETECT, RX_DETECT_SOP);
214 if (!r8(CC_STATUS, cc))
return false;
216 uint8_t cc1 = cc & 0x03;
217 uint8_t cc2 = (cc >> 2) & 0x03;
218 return w8(TCPC_CONTROL, (cc2 != 0 && cc1 == 0) ? 0x01 : 0x00);
224 if (!r8(CC_STATUS, cc))
return false;
226 auto decodeSinkCc = [](uint8_t raw) ->
CcStatus {
236 cc1 = decodeSinkCc(cc);
237 cc2 = decodeSinkCc(cc >> 2);
245 if (!
getCc(cc1, cc2))
return false;
251 return r8(POWER_STATUS, status);
258 return (status & POWER_STATUS_VBUS_PRESENT) != 0;
263 uint8_t lo = 0, hi = 0;
264 if (!r8(VBUS_VOLTAGE_L, lo))
return false;
265 if (!r8(VBUS_VOLTAGE_H, hi))
return false;
267 uint16_t raw =
static_cast<uint16_t
>(lo) | (
static_cast<uint16_t
>(hi & 0x07) << 8);
268 mv =
static_cast<uint16_t
>(raw * 14);
276 uint8_t
buf[32] = {0};
277 if (!readNoInc(RX_BYTE_CNT,
buf,
sizeof(
buf)))
return false;
279 uint8_t count =
buf[0];
280 uint8_t frameType =
buf[1];
281 if (count == 0 || count > 30 || count < 3)
return false;
282 if (frameType != 0x00 && frameType != 0x01)
return false;
286 out.
headerLE =
static_cast<uint16_t
>(
buf[2]) | (
static_cast<uint16_t
>(
buf[3]) << 8);
288 uint8_t payloadLen =
static_cast<uint8_t
>(count - 3);
289 if (payloadLen >
sizeof(out.
payload)) payloadLen =
sizeof(out.
payload);
291 for (uint8_t
i = 0;
i < payloadLen; ++
i) {
299 const uint8_t *payload, uint8_t payloadLen)
301 if (payloadLen > 28) payloadLen = 28;
302 if (payloadLen && !payload)
return false;
306 uint8_t
buf[31] = {0};
307 buf[0] =
static_cast<uint8_t
>(payloadLen + 2);
308 buf[1] =
static_cast<uint8_t
>(headerLE & 0xFF);
309 buf[2] =
static_cast<uint8_t
>((headerLE >> 8) & 0xFF);
310 for (uint8_t
i = 0;
i < payloadLen; ++
i) {
311 buf[3 +
i] = payload[
i];
313 if (!writeNoInc(TX_BYTE_CNT,
buf,
static_cast<uint8_t
>(payloadLen + 3))) {
318 uint8_t retryValue = orderedSet ? 0 :
static_cast<uint8_t
>(retry);
319 uint8_t tx =
static_cast<uint8_t
>(((retryValue & 0x03) << 4) |
320 (
static_cast<uint8_t
>(type) & 0x07));
321 return w8(TX_BUF_TRANSMIT, tx);
void delayMs(uint32_t ms)
Delay using the active platform HAL.
bool enableModule(Module module, bool enable)
Enable or disable a module.
@ TYPEC
REG 0BH bit 3 Type-C.
bool writeMessageHeaderInfo(uint8_t v)
Write the TCPCI MESSAGE_HEADER_INFO register.
bool clearAlert(uint16_t maskRw1c)
Clear PD_ALERTL/H bits using write-one-to-clear semantics.
bool setSinkMessageHeaderAndRx()
Configure sink message-header defaults and enable SOP RX.
bool clearPmicIrqStatus()
Clear the non-PD PMIC IRQ status registers.
bool init()
Initialize the TCPC as a USB-PD sink.
bool clearTx()
Reset the TX byte count and transmit command register.
bool txSend(TransmitType type, RetryCount retry, uint16_t headerLE, const uint8_t *payload, uint8_t payloadLen)
Send a USB-PD packet through the TCPC TX FIFO.
bool clearFaultStatus(uint8_t maskRw1c)
Clear TCPC FAULT_STATUS bits using write-one-to-clear semantics.
bool isAttached()
Check whether either CC pin indicates attachment.
RetryCount
TCPCI transmit retry count values.
bool readFaultStatus(uint8_t &out)
Read the TCPC FAULT_STATUS register.
bool getCc(CcStatus &cc1, CcStatus &cc2)
Read and decode CC1/CC2 status.
CcStatus
Decoded sink-side CC status.
@ RP_1_5
1.5 A current advertisement.
@ RP_DEF
Default USB current advertisement.
@ OPEN
No source detected on this CC pin.
@ RP_3_0
3.0 A current advertisement.
bool writeReceiveDetect(uint8_t v)
Write the TCPCI RECEIVE_DETECT register.
bool readVbusMv(uint16_t &mv)
Read TCPC VBUS ADC value.
bool readAlert(uint16_t &out)
Read PD_ALERTL/H.
bool rxReadMessage(RxFifoMsg &out)
Read and decode one TCPC RX FIFO message.
bool checkVendorId()
Verify the TCPC vendor ID.
bool getPowerStatus(uint8_t &status)
Read POWER_STATUS.
bool clearAllAlerts()
Clear all PD alert bits.
TransmitType
TCPCI TRANSMIT register packet type values.
@ HARD_RESET
Hard Reset ordered set.
@ CABLE_RESET
Cable Reset ordered set.
bool isVbusPresent()
Check whether TCPC VBUS present status is set.
bool setPolarityFromCc()
Set TCPC polarity from the current CC status.
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
AXP517 TCPC register addresses, alert bits, and command constants.
uint16_t headerLE
USB-PD message header in little-endian order.
uint8_t frameType
TCPCI RX frame type.
uint8_t byteCount
TCPCI readable byte count.
uint8_t payload[28]
USB-PD payload bytes.
uint8_t payloadLen
Number of valid payload bytes.
static constexpr uint8_t ENABLE
ADC channel enable control.
static constexpr uint8_t STATUS3
IRQ Status 3.
static constexpr uint8_t STATUS0
IRQ Status 0.