/** * @file test_bq25756_hal.c * @brief BQ25756 HAL 集成测试 — Mock I2C 寄存器读写验证 * * 用 256 字节寄存器镜像模拟 BQ25756, 验证所有 HAL 函数的读写正确性。 * 编译: 见 Makefile */ #include "test_common.h" #include "mock_stm32.h" #include "bq25756_regs.h" #include "bq25756_hal.h" /* === 辅助: 设置 mock 寄存器值 === */ static void set_mock_vbat(uint32_t mv) { mock_i2c_set_reg16(BQ25756_REG_VBAT_ADC, (uint16_t)(mv / 2)); } static void set_mock_ibat(int32_t ma) { mock_i2c_set_reg16(BQ25756_REG_IBAT_ADC, (uint16_t)(ma / 2)); } static void set_mock_vin(uint32_t mv) { mock_i2c_set_reg16(BQ25756_REG_VAC_ADC, (uint16_t)(mv / 2)); } static void set_mock_iin(int32_t ma) { mock_i2c_set_reg16(BQ25756_REG_IAC_ADC, (uint16_t)(ma / 2)); } /* ================================================================= * ADC 读数测试 * ================================================================= */ /** VBAT_ADC 0x396C (=14700 LSBs x 2mV = 29400mV) → bq_read_vbat_mv() */ TEST(read_vbat_29400mv) { mock_i2c_reset(); set_mock_vbat(29400); ASSERT_EQ(bq_read_vbat_mv(), 29400); } /** VBAT_ADC=0 → 0mV */ TEST(read_vbat_zero) { mock_i2c_reset(); set_mock_vbat(0); ASSERT_EQ(bq_read_vbat_mv(), 0); } /** IBAT_ADC 0x03E8 (=1000 LSBs x 2mA = 2000mA, 充电) */ TEST(read_ibat_2000ma_charging) { mock_i2c_reset(); set_mock_ibat(2000); ASSERT_EQ(bq_read_ibat_ma(), 2000); } /** IBAT_ADC 负值 (= -500mA, 放电) */ TEST(read_ibat_negative_discharging) { mock_i2c_reset(); set_mock_ibat(-500); ASSERT_EQ(bq_read_ibat_ma(), -500); } /** VAC_ADC 0x2EE0 (=12000 LSBs x 2mV = 24000mV, 24V DC) */ TEST(read_vin_24000mv) { mock_i2c_reset(); set_mock_vin(24000); ASSERT_EQ(bq_read_vin_mv(), 24000); } /** IAC_ADC 0x05DC (=1500 LSBs x 2mA = 3000mA) */ TEST(read_iin_3000ma) { mock_i2c_reset(); set_mock_iin(3000); ASSERT_EQ(bq_read_iin_ma(), 3000); } /* ================================================================= * 寄存器写入测试 * ================================================================= */ /** bq_write_charge_current(2000) → REG0x02 = (2000/50)<<2 = 0x00A0 */ TEST(write_charge_current_2000ma) { mock_i2c_reset(); ASSERT_EQ(bq_write_charge_current(2000), 0); uint16_t raw = mock_regs_get_16(BQ25756_REG_CHG_CURRENT); ASSERT_EQ(raw, (uint16_t)((2000 / 50) << 2)); } /** 电流 <400mA 应 clamp 到 400mA */ TEST(write_charge_current_clamp_low) { mock_i2c_reset(); ASSERT_EQ(bq_write_charge_current(100), 0); uint16_t raw = mock_regs_get_16(BQ25756_REG_CHG_CURRENT); ASSERT_EQ(raw, (uint16_t)((400 / 50) << 2)); } /** 电流 >20000mA 应 clamp 到 20000mA */ TEST(write_charge_current_clamp_high) { mock_i2c_reset(); ASSERT_EQ(bq_write_charge_current(30000), 0); uint16_t raw = mock_regs_get_16(BQ25756_REG_CHG_CURRENT); ASSERT_EQ(raw, (uint16_t)((20000 / 50) << 2)); } /** 预充电流 200mA (<250mA min) → clamp 到 250mA */ TEST(write_precharge_current_200ma) { mock_i2c_reset(); ASSERT_EQ(bq_write_precharge_current(200), 0); uint16_t raw = mock_regs_get_16(BQ25756_REG_PRECHG_CURRENT); ASSERT_EQ(raw, (uint16_t)((250 / 50) << 2)); } /* ================================================================= * 读改写(RMW)测试 * ================================================================= */ /** EN_CHG 使能 → REG0x17 bit0=1, 禁用 → bit0=0, 其他位不变 */ TEST(set_en_chg_read_modify_write) { mock_i2c_reset(); mock_i2c_set_reg(BQ25756_REG_CHARGER_CTRL, 0x00); ASSERT_EQ(bq_set_en_chg(1), 0); uint8_t ctrl = mock_regs_get_8(BQ25756_REG_CHARGER_CTRL); ASSERT_NEQ(ctrl & BQ25756_EN_CHG, 0); ASSERT_EQ(bq_set_en_chg(0), 0); ctrl = mock_regs_get_8(BQ25756_REG_CHARGER_CTRL); ASSERT_EQ(ctrl & BQ25756_EN_CHG, 0); } /** WD_RST 位置位 → REG0x17 bit5=1 */ TEST(reset_watchdog_sets_wd_rst_bit) { mock_i2c_reset(); mock_i2c_set_reg(BQ25756_REG_CHARGER_CTRL, 0x00); ASSERT_EQ(bq_reset_wd(), 0); uint8_t ctrl = mock_regs_get_8(BQ25756_REG_CHARGER_CTRL); ASSERT_NEQ(ctrl & BQ25756_WD_RST, 0); } /** EN_PFM 使能/禁用 → REG0x19 bit5 */ TEST(set_en_pfm) { mock_i2c_reset(); mock_i2c_set_reg(BQ25756_REG_POWER_PATH_REV, 0x00); ASSERT_EQ(bq_set_en_pfm(1), 0); ASSERT_NEQ(mock_regs_get_8(BQ25756_REG_POWER_PATH_REV) & BQ25756_EN_PFM, 0); ASSERT_EQ(bq_set_en_pfm(0), 0); ASSERT_EQ(mock_regs_get_8(BQ25756_REG_POWER_PATH_REV) & BQ25756_EN_PFM, 0); } /* ================================================================= * MPPT 测试 * ================================================================= */ /** bq_mppt_start() → EN_MPPT=1, FS=20min */ TEST(mppt_start_writes_correct_value) { mock_i2c_reset(); ASSERT_EQ(bq_mppt_start(), 0); ASSERT_NEQ(mock_regs_get_8(BQ25756_REG_MPPT_CTRL) & BQ25756_EN_MPPT, 0); } /** bq_mppt_stop() → EN_MPPT=0 */ TEST(mppt_stop_clears_en_mppt) { mock_i2c_reset(); mock_i2c_set_reg(BQ25756_REG_MPPT_CTRL, BQ25756_EN_MPPT); ASSERT_EQ(bq_mppt_stop(), 0); ASSERT_EQ(mock_regs_get_8(BQ25756_REG_MPPT_CTRL) & BQ25756_EN_MPPT, 0); } /** bq_mppt_force_sweep() → FORCE_SWEEP 位=1 */ TEST(mppt_force_sweep_sets_bit) { mock_i2c_reset(); mock_i2c_set_reg(BQ25756_REG_MPPT_CTRL, BQ25756_EN_MPPT); ASSERT_EQ(bq_mppt_force_sweep(), 0); ASSERT_NEQ(mock_regs_get_8(BQ25756_REG_MPPT_CTRL) & BQ25756_FORCE_SWEEP, 0); } /* ================================================================= * 软启动 / 中断 / 初始化测试 * ================================================================= */ /** soft_start(2000) → 最终 REG0x02 = (2000/50)<<2 */ TEST(soft_start_ramps_correctly) { mock_i2c_reset(); ASSERT_EQ(bq_soft_start(2000, NULL), 0); ASSERT_EQ(mock_regs_get_16(BQ25756_REG_CHG_CURRENT), (uint16_t)((2000/50)<<2)); } /** int_mask_only_fault → MASK1=0xFF, MASK2=0xFF, FAULT_MASK=0x00 */ TEST(int_mask_only_fault) { mock_i2c_reset(); bq_int_mask_only_fault(); ASSERT_EQ(mock_regs_get_8(BQ25756_REG_MASK_1), 0xFF); ASSERT_EQ(mock_regs_get_8(BQ25756_REG_MASK_2), 0xFF); ASSERT_EQ(mock_regs_get_8(BQ25756_REG_FAULT_MASK), 0x00); } /** bq_watchdog_off() → REG0x15 = 0x0D */ TEST(watchdog_off_writes_correct_value) { mock_i2c_reset(); ASSERT_EQ(bq_watchdog_off(), 0); ASSERT_EQ(mock_regs_get_8(0x15), 0x0D); } /** bq_ntc_off() → REG0x1C = 0x56 */ TEST(ntc_off_writes_correct_value) { mock_i2c_reset(); ASSERT_EQ(bq_ntc_off(), 0); ASSERT_EQ(mock_regs_get_8(0x1C), 0x56); } #define TEST_LIST \ RUN_TEST(read_vbat_29400mv); \ RUN_TEST(read_vbat_zero); \ RUN_TEST(read_ibat_2000ma_charging); \ RUN_TEST(read_ibat_negative_discharging); \ RUN_TEST(read_vin_24000mv); \ RUN_TEST(read_iin_3000ma); \ RUN_TEST(write_charge_current_2000ma); \ RUN_TEST(write_charge_current_clamp_low); \ RUN_TEST(write_charge_current_clamp_high); \ RUN_TEST(write_precharge_current_200ma); \ RUN_TEST(set_en_chg_read_modify_write); \ RUN_TEST(reset_watchdog_sets_wd_rst_bit); \ RUN_TEST(set_en_pfm); \ RUN_TEST(mppt_start_writes_correct_value); \ RUN_TEST(mppt_stop_clears_en_mppt); \ RUN_TEST(mppt_force_sweep_sets_bit); \ RUN_TEST(soft_start_ramps_correctly); \ RUN_TEST(int_mask_only_fault); \ RUN_TEST(watchdog_off_writes_correct_value); \ RUN_TEST(ntc_off_writes_correct_value); int main(void) { RUN_ALL; return __test_fail; }