#include "axp2101.h" #include "hal_interface.h" #define AXP2101_DEV_I2C_ID 0x68 extern I2C_HandleTypeDef hi2c2; static uint8_t statusRegister[XPOWERS_AXP2101_INTSTS_CNT] = {0}; static uint8_t intRegister[XPOWERS_AXP2101_INTSTS_CNT] = {0}; __STATIC_INLINE uint8_t clrRegisterBit(uint8_t registers, uint8_t bit) { uint8_t reg_value = 0; HAL_StatusTypeDef status; status = HAL_I2C_Mem_Read(&hi2c2, AXP2101_DEV_I2C_ID, registers, 1, ®_value, 1, 60); if (status != HAL_OK) return 1; reg_value &= (uint8_t)(~_BV(bit)); return HAL_I2C_Mem_Write(&hi2c2, AXP2101_DEV_I2C_ID, registers, 1, ®_value, 1, 60); } __STATIC_INLINE uint8_t getRegisterBit(uint8_t registers, uint8_t bit) { uint8_t reg_value = 0; HAL_StatusTypeDef status; status = HAL_I2C_Mem_Read(&hi2c2, AXP2101_DEV_I2C_ID, registers, 1, ®_value, 1, 60); if (status != HAL_OK) return 1; return reg_value & _BV(bit); } __STATIC_INLINE uint8_t setRegisterBit(uint8_t registers, uint8_t bit) { uint8_t reg_value = 0; HAL_StatusTypeDef status; status = HAL_I2C_Mem_Read(&hi2c2, AXP2101_DEV_I2C_ID, registers, 1, ®_value, 1, 60); if (status != HAL_OK) return 1; reg_value |= (uint8_t)(_BV(bit)); return HAL_I2C_Mem_Write(&hi2c2, AXP2101_DEV_I2C_ID, registers, 1, ®_value, 1, 60); } uint32_t setInterruptImpl(uint32_t opts, uint8_t enable) { uint8_t reg_value = 0; HAL_StatusTypeDef status = HAL_OK; if (opts & 0x0000FF) { HAL_I2C_Mem_Read(&hi2c2, AXP2101_DEV_I2C_ID, XPOWERS_AXP2101_INTEN1, 1, ®_value, 1, 60); intRegister[0] = enable ? (uint8_t)(reg_value | (opts & 0xFF)) : (uint8_t)(reg_value & (~(opts & 0xFF))); status |= HAL_I2C_Mem_Write(&hi2c2, 0x68, XPOWERS_AXP2101_INTEN1, 1, &intRegister[0], 1, 60); } if (opts & 0x00FF00) { HAL_I2C_Mem_Read(&hi2c2, AXP2101_DEV_I2C_ID, XPOWERS_AXP2101_INTEN2, 1, ®_value, 1, 60); intRegister[1] = enable ? (uint8_t)(reg_value | (opts >> 8)) : (uint8_t)(reg_value & (~(opts >> 8))); status |= HAL_I2C_Mem_Write(&hi2c2, 0x68, XPOWERS_AXP2101_INTEN2, 1, &intRegister[1], 1, 60); } if (opts & 0xFF0000) { HAL_I2C_Mem_Read(&hi2c2, AXP2101_DEV_I2C_ID, XPOWERS_AXP2101_INTEN3, 1, ®_value, 1, 60); intRegister[2] = enable ? (uint8_t)(reg_value | (opts >> 16)) : (uint8_t)(reg_value & (~(opts >> 16))); status |= HAL_I2C_Mem_Write(&hi2c2, 0x68, XPOWERS_AXP2101_INTEN3, 1, &intRegister[2], 1, 60); } return (uint32_t)status; } uint32_t AXP2101_shutdown(void) { return setRegisterBit(XPOWERS_AXP2101_COMMON_CONFIG, 0); } uint32_t AXP2101_disableTSPinMeasure(void) { return clrRegisterBit(XPOWERS_AXP2101_ADC_CHANNEL_CTRL, 1); } uint32_t AXP2101_enableBattDetection(void) { return setRegisterBit(XPOWERS_AXP2101_BAT_DET_CTRL, 0); } uint32_t AXP2101_enableBattVoltageMeasure(void) { return setRegisterBit(XPOWERS_AXP2101_ADC_CHANNEL_CTRL, 0); } uint32_t AXP2101_enableSystemVoltageMeasure(void) { return setRegisterBit(XPOWERS_AXP2101_ADC_CHANNEL_CTRL, 3); } uint32_t AXP2101_enableVbusVoltageMeasure(void) { return setRegisterBit(XPOWERS_AXP2101_ADC_CHANNEL_CTRL, 2); } uint32_t AXP2101_enableIRQ(uint32_t opt) { return setInterruptImpl(opt, 1); } uint32_t AXP2101_disableIRQ(uint32_t opt) { return setInterruptImpl(opt, 0); } uint32_t AXP2101_clearIrqStatus(void) { HAL_StatusTypeDef status = HAL_OK; uint8_t fbuff = 0xFF; for (size_t i = 0; i < XPOWERS_AXP2101_INTSTS_CNT; i++) { status |= HAL_I2C_Mem_Write(&hi2c2, AXP2101_DEV_I2C_ID, XPOWERS_AXP2101_INTSTS1 + (uint8_t)i, 1, &fbuff, 1, 60); statusRegister[i] = 0; } return (uint32_t)status; } uint8_t AXP2101_isDropWarningLevel1Irq(void) { uint8_t mask = XPOWERS_AXP2101_WARNING_LEVEL1_IRQ; if (intRegister[0] & mask) return ((statusRegister[0] & mask) == mask); return 0; } uint8_t AXP2101_isVbusRemoveIrq(void) { uint8_t mask = XPOWERS_AXP2101_VBUS_REMOVE_IRQ >> 8; if (intRegister[1] & mask) return ((statusRegister[1] & mask) == mask); return 0; } uint8_t AXP2101_isBatInsertIrq(void) { uint8_t mask = XPOWERS_AXP2101_BAT_INSERT_IRQ >> 8; if (intRegister[1] & mask) return ((statusRegister[1] & mask) == mask); return 0; } uint8_t AXP2101_isBatRemoveIrq(void) { uint8_t mask = XPOWERS_AXP2101_BAT_REMOVE_IRQ >> 8; if (intRegister[1] & mask) return ((statusRegister[1] & mask) == mask); return 0; } uint8_t AXP2101_isPekeyShortPressIrq(void) { uint8_t mask = XPOWERS_AXP2101_PKEY_SHORT_IRQ >> 8; if (intRegister[1] & mask) return ((statusRegister[1] & mask) == mask); return 0; } uint8_t AXP2101_isPekeyLongPressIrq(void) { uint8_t mask = XPOWERS_AXP2101_PKEY_LONG_IRQ >> 8; if (intRegister[1] & mask) return ((statusRegister[1] & mask) == mask); return 0; } uint8_t AXP2101_isBatChargeDoneIrq(void) { uint8_t mask = XPOWERS_AXP2101_BAT_CHG_DONE_IRQ >> 16; if (intRegister[2] & mask) return ((statusRegister[2] & mask) == mask); return 0; } uint8_t AXP2101_isBatChargeStartIrq(void) { uint8_t mask = XPOWERS_AXP2101_BAT_CHG_START_IRQ >> 16; if (intRegister[2] & mask) return ((statusRegister[2] & mask) == mask); return 0; } // value in mV uint32_t AXP2101_setSysPowerDownVoltage(uint16_t value) { uint8_t reg_value = 0; HAL_StatusTypeDef status; if (value % XPOWERS_AXP2101_VSYS_VOL_THRESHOLD_STEPS) { //log_e("Mistake ! The steps is must %u mV", XPOWERS_AXP2101_VSYS_VOL_THRESHOLD_STEPS); return 10; } if (value < XPOWERS_AXP2101_VSYS_VOL_THRESHOLD_MIN) { //log_e("Mistake ! The minimum settable voltage of VSYS is %u mV", XPOWERS_AXP2101_VSYS_VOL_THRESHOLD_MIN); return 10; } else if (value > XPOWERS_AXP2101_VSYS_VOL_THRESHOLD_MAX) { //log_e("Mistake ! The maximum settable voltage of VSYS is %u mV", XPOWERS_AXP2101_VSYS_VOL_THRESHOLD_MAX); return 10; } status = HAL_I2C_Mem_Read(&hi2c2, AXP2101_DEV_I2C_ID, XPOWERS_AXP2101_VOFF_SET, 1, ®_value, 1, 60); if (status != HAL_OK) return 1; reg_value &= 0xF8; reg_value |= (uint8_t)((value - XPOWERS_AXP2101_VSYS_VOL_THRESHOLD_MIN) / XPOWERS_AXP2101_VSYS_VOL_THRESHOLD_STEPS); return (uint32_t)HAL_I2C_Mem_Write(&hi2c2, AXP2101_DEV_I2C_ID, XPOWERS_AXP2101_VOFF_SET, 1, ®_value, 1, 60); } uint32_t AXP2101_setChargingLedMode(uint8_t mode) { uint8_t reg_value = 0; HAL_StatusTypeDef status; switch (mode) { case XPOWERS_CHG_LED_OFF: // clrRegisterBit(XPOWERS_AXP2101_CHGLED_SET_CTRL, 0); // break; case XPOWERS_CHG_LED_BLINK_1HZ: case XPOWERS_CHG_LED_BLINK_4HZ: case XPOWERS_CHG_LED_ON: status = HAL_I2C_Mem_Read(&hi2c2, AXP2101_DEV_I2C_ID, XPOWERS_AXP2101_CHGLED_SET_CTRL, 1, ®_value, 1, 60); if (status != HAL_OK) return 1; reg_value &= 0xC8; reg_value |= 0x05; //use manual ctrl reg_value |= (mode << 4); status = HAL_I2C_Mem_Write(&hi2c2, AXP2101_DEV_I2C_ID, XPOWERS_AXP2101_CHGLED_SET_CTRL, 1, ®_value, 1, 60); break; case XPOWERS_CHG_LED_CTRL_CHG: status = HAL_I2C_Mem_Read(&hi2c2, AXP2101_DEV_I2C_ID, XPOWERS_AXP2101_CHGLED_SET_CTRL, 1, ®_value, 1, 60); if (status != HAL_OK) return 1; reg_value &= 0xF9; reg_value |= 0x01; // use type A mode //reg_value |= 0x02; // use type B mode status = HAL_I2C_Mem_Write(&hi2c2, AXP2101_DEV_I2C_ID, XPOWERS_AXP2101_CHGLED_SET_CTRL, 1, ®_value, 1, 60); break; default: status = 10; break; } return (uint32_t)status; } /** * @brief Low battery warning threshold 5-20%, 1% per step * @param percentage: 5 ~ 20 * @retval Status code */ uint32_t AXP2101_setLowBatWarnThreshold(uint8_t percentage) { if (percentage < 5 || percentage > 20) return 1; uint8_t reg_value = 0; HAL_StatusTypeDef status; status = HAL_I2C_Mem_Read(&hi2c2, AXP2101_DEV_I2C_ID, XPOWERS_AXP2101_LOW_BAT_WARN_SET, 1, ®_value, 1, 60); if (status != HAL_OK) return 1; reg_value &= 0x0F; reg_value |= (uint8_t)((percentage - 5) << 4); return HAL_I2C_Mem_Write(&hi2c2, AXP2101_DEV_I2C_ID, XPOWERS_AXP2101_LOW_BAT_WARN_SET, 1, ®_value, 1, 60); } /** * @brief Low battery shutdown threshold 0-15%, 1% per step * @param opt: 0 ~ 15 * @retval Status code */ uint32_t AXP2101_setLowBatShutdownThreshold(uint8_t opt) { uint8_t reg_value = 0; HAL_StatusTypeDef status; if (opt > 15) opt = 15; status = HAL_I2C_Mem_Read(&hi2c2, AXP2101_DEV_I2C_ID, XPOWERS_AXP2101_LOW_BAT_WARN_SET, 1, ®_value, 1, 60); if (status != HAL_OK) return 1; reg_value &= 0xF0; reg_value |= opt; return HAL_I2C_Mem_Write(&hi2c2, AXP2101_DEV_I2C_ID, XPOWERS_AXP2101_LOW_BAT_WARN_SET, 1, ®_value, 1, 60); } uint8_t AXP2101_isBatteryConnect(void) { return getRegisterBit(XPOWERS_AXP2101_STATUS1, 3); } uint8_t AXP2101_isCharging(void) { uint8_t reg_value = 0; HAL_I2C_Mem_Read(&hi2c2, AXP2101_DEV_I2C_ID, XPOWERS_AXP2101_STATUS2, 1, ®_value, 1, 60); return (reg_value >> 5) == 0x01; } uint32_t AXP2101_getIrqStatus(uint32_t* out_value) { HAL_StatusTypeDef status = HAL_OK; status |= HAL_I2C_Mem_Read(&hi2c2, AXP2101_DEV_I2C_ID, XPOWERS_AXP2101_INTSTS1, 1, &statusRegister[0], 1, 60); status |= HAL_I2C_Mem_Read(&hi2c2, AXP2101_DEV_I2C_ID, XPOWERS_AXP2101_INTSTS2, 1, &statusRegister[1], 1, 60); status |= HAL_I2C_Mem_Read(&hi2c2, AXP2101_DEV_I2C_ID, XPOWERS_AXP2101_INTSTS3, 1, &statusRegister[2], 1, 60); ((uint8_t*)&out_value)[0] = statusRegister[0]; ((uint8_t*)&out_value)[0] = statusRegister[1]; ((uint8_t*)&out_value)[0] = statusRegister[2]; ((uint8_t*)&out_value)[3] = 0xFF; return (uint32_t)status; } uint32_t AXP2101_getBatteryPercent(uint8_t* out_value) { if (!AXP2101_isBatteryConnect()) return 1; return HAL_I2C_Mem_Read(&hi2c2, AXP2101_DEV_I2C_ID, XPOWERS_AXP2101_BAT_PERCENT_DATA, 1, out_value, 1, 60); }