/ RNode_Firmware_CE_G2 / Power.h
Power.h
1 // Copyright (C) 2024, Mark Qvist 2 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU General Public License as published by 5 // the Free Software Foundation, either version 3 of the License, or 6 // (at your option) any later version. 7 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU General Public License for more details. 12 13 // You should have received a copy of the GNU General Public License 14 // along with this program. If not, see <https://www.gnu.org/licenses/>. 15 16 #define PMU_TEMP_MIN -30 17 #define PMU_TEMP_MAX 90 18 #define PMU_TEMP_OFFSET 120 19 bool pmu_temp_sensor_ready = false; 20 float pmu_temperature = PMU_TEMP_MIN-1; 21 22 #if BOARD_MODEL == BOARD_TBEAM || BOARD_MODEL == BOARD_TBEAM_S_V1 23 #include <XPowersLib.h> 24 XPowersLibInterface* PMU = NULL; 25 26 #ifndef PMU_WIRE_PORT 27 #if BOARD_MODEL == BOARD_TBEAM_S_V1 28 #define PMU_WIRE_PORT Wire1 29 #else 30 #define PMU_WIRE_PORT Wire 31 #endif 32 #endif 33 34 #define BAT_V_MIN 3.15 35 #define BAT_V_MAX 4.14 36 37 void disablePeripherals() { 38 if (PMU) { 39 // GNSS RTC PowerVDD 40 PMU->enablePowerOutput(XPOWERS_VBACKUP); 41 42 // LoRa VDD 43 PMU->disablePowerOutput(XPOWERS_ALDO2); 44 45 // GNSS VDD 46 PMU->disablePowerOutput(XPOWERS_ALDO3); 47 } 48 } 49 50 bool pmuInterrupt; 51 void setPmuFlag() 52 { 53 pmuInterrupt = true; 54 } 55 #elif BOARD_MODEL == BOARD_RNODE_NG_21 || BOARD_MODEL == BOARD_LORA32_V2_1 56 #define BAT_V_MIN 3.15 57 #define BAT_V_MAX 4.3 58 #define BAT_V_CHG 4.48 59 #define BAT_V_FLOAT 4.33 60 #define BAT_SAMPLES 5 61 const uint8_t pin_vbat = 35; 62 float bat_p_samples[BAT_SAMPLES]; 63 float bat_v_samples[BAT_SAMPLES]; 64 uint8_t bat_samples_count = 0; 65 int bat_discharging_samples = 0; 66 int bat_charging_samples = 0; 67 int bat_charged_samples = 0; 68 bool bat_voltage_dropping = false; 69 float bat_delay_v = 0; 70 float bat_state_change_v = 0; 71 #elif BOARD_MODEL == BOARD_T3S3 72 #define BAT_V_MIN 3.15 73 #define BAT_V_MAX 4.217 74 #define BAT_V_CHG 4.48 75 #define BAT_V_FLOAT 4.33 76 #define BAT_SAMPLES 5 77 const uint8_t pin_vbat = 1; 78 float bat_p_samples[BAT_SAMPLES]; 79 float bat_v_samples[BAT_SAMPLES]; 80 uint8_t bat_samples_count = 0; 81 int bat_discharging_samples = 0; 82 int bat_charging_samples = 0; 83 int bat_charged_samples = 0; 84 bool bat_voltage_dropping = false; 85 float bat_delay_v = 0; 86 float bat_state_change_v = 0; 87 #elif BOARD_MODEL == BOARD_TDECK 88 #define BAT_V_MIN 3.15 89 #define BAT_V_MAX 4.3 90 #define BAT_V_CHG 4.48 91 #define BAT_V_FLOAT 4.33 92 #define BAT_SAMPLES 5 93 const uint8_t pin_vbat = 4; 94 float bat_p_samples[BAT_SAMPLES]; 95 float bat_v_samples[BAT_SAMPLES]; 96 uint8_t bat_samples_count = 0; 97 int bat_discharging_samples = 0; 98 int bat_charging_samples = 0; 99 int bat_charged_samples = 0; 100 bool bat_voltage_dropping = false; 101 float bat_delay_v = 0; 102 float bat_state_change_v = 0; 103 #elif BOARD_MODEL == BOARD_HELTEC32_V3 104 // Unless we implement some real voodoo 105 // on these boards, we can't say with 106 // any certainty whether we are actually 107 // charging and have reached a charge 108 // complete state. The *only* data point 109 // we have to go from is the bus voltage. 110 // The BAT_V_CHG and BAT_V_FLOAT values 111 // are set high here to avoid the display 112 // indication confusingly flapping 113 // between charge completed, charging and 114 // discharging states. 115 // Update: Vodoo implemented. Hopefully 116 // it will work accross different boards. 117 #define BAT_V_MIN 3.05 118 #define BAT_V_MAX 4.0 119 #define BAT_V_CHG 4.48 120 #define BAT_V_FLOAT 4.33 121 #define BAT_SAMPLES 7 122 const uint8_t pin_vbat = 1; 123 const uint8_t pin_ctrl = 37; 124 float bat_p_samples[BAT_SAMPLES]; 125 float bat_v_samples[BAT_SAMPLES]; 126 uint8_t bat_samples_count = 0; 127 int bat_discharging_samples = 0; 128 int bat_charging_samples = 0; 129 int bat_charged_samples = 0; 130 bool bat_voltage_dropping = false; 131 float bat_delay_v = 0; 132 float bat_state_change_v = 0; 133 #elif BOARD_MODEL == BOARD_HELTEC32_V4 134 #define BAT_V_MIN 3.05 135 #define BAT_V_MAX 4.0 136 #define BAT_V_CHG 4.48 137 #define BAT_V_FLOAT 4.33 138 #define BAT_SAMPLES 7 139 const uint8_t pin_vbat = 1; 140 const uint8_t pin_ctrl = 37; 141 float bat_p_samples[BAT_SAMPLES]; 142 float bat_v_samples[BAT_SAMPLES]; 143 uint8_t bat_samples_count = 0; 144 int bat_discharging_samples = 0; 145 int bat_charging_samples = 0; 146 int bat_charged_samples = 0; 147 bool bat_voltage_dropping = false; 148 float bat_delay_v = 0; 149 float bat_state_change_v = 0; 150 #elif BOARD_MODEL == BOARD_HELTEC_T114 151 #define BAT_V_MIN 3.15 152 #define BAT_V_MAX 4.165 153 #define BAT_V_CHG 4.48 154 #define BAT_V_FLOAT 4.33 155 #define BAT_SAMPLES 7 156 const uint8_t pin_vbat = 4; 157 const uint8_t pin_ctrl = 6; 158 float bat_p_samples[BAT_SAMPLES]; 159 float bat_v_samples[BAT_SAMPLES]; 160 uint8_t bat_samples_count = 0; 161 int bat_discharging_samples = 0; 162 int bat_charging_samples = 0; 163 int bat_charged_samples = 0; 164 bool bat_voltage_dropping = false; 165 float bat_delay_v = 0; 166 float bat_state_change_v = 0; 167 #elif BOARD_MODEL == BOARD_TECHO 168 #define BAT_V_MIN 3.15 169 #define BAT_V_MAX 4.16 170 #define BAT_V_CHG 4.48 171 #define BAT_V_FLOAT 4.33 172 #define BAT_SAMPLES 7 173 const uint8_t pin_vbat = 4; 174 float bat_p_samples[BAT_SAMPLES]; 175 float bat_v_samples[BAT_SAMPLES]; 176 uint8_t bat_samples_count = 0; 177 int bat_discharging_samples = 0; 178 int bat_charging_samples = 0; 179 int bat_charged_samples = 0; 180 bool bat_voltage_dropping = false; 181 float bat_delay_v = 0; 182 float bat_state_change_v = 0; 183 #endif 184 185 uint32_t last_pmu_update = 0; 186 // Battery/temp sampling interval (ms); lower rate saves a little CPU/ADC without affecting radio. 187 #define PMU_UPDATE_INTERVAL_MS 2000 188 int pmu_update_interval = PMU_UPDATE_INTERVAL_MS; 189 uint8_t pmu_charged_ascertain = 0; 190 uint8_t pmu_rc = 0; 191 uint8_t pmu_sc = 0; 192 float bat_delay_diff = 0; 193 bool bat_diff_positive = false; 194 #define PMU_R_INTERVAL 5 195 #define PMU_SCV_RESET_INTERVAL 3 196 void kiss_indicate_battery(); 197 void kiss_indicate_temperature(); 198 199 void measure_temperature() { 200 #if PLATFORM == PLATFORM_ESP32 201 if (pmu_temp_sensor_ready) { pmu_temperature = temperatureRead(); } else { pmu_temperature = PMU_TEMP_MIN-1; } 202 #endif 203 } 204 205 void measure_battery() { 206 #if BOARD_MODEL == BOARD_RNODE_NG_21 || BOARD_MODEL == BOARD_LORA32_V2_1 || BOARD_MODEL == BOARD_HELTEC32_V3 || BOARD_MODEL == BOARD_HELTEC32_V4 || BOARD_MODEL == BOARD_TDECK || BOARD_MODEL == BOARD_T3S3 || BOARD_MODEL == BOARD_HELTEC_T114 || BOARD_MODEL == BOARD_TECHO 207 battery_installed = true; 208 #if BOARD_MODEL == BOARD_HELTEC32_V3 || BOARD_MODEL == BOARD_HELTEC32_V4 209 battery_indeterminate = false; 210 #else 211 battery_indeterminate = true; 212 #endif 213 214 #if BOARD_MODEL == BOARD_HELTEC32_V3 215 float battery_measurement = (float)(analogRead(pin_vbat)) * 0.0041; 216 #elif BOARD_MODEL == BOARD_HELTEC32_V4 217 float battery_measurement = (float)(analogRead(pin_vbat)) * 0.00418; 218 #elif BOARD_MODEL == BOARD_T3S3 219 float battery_measurement = (float)(analogRead(pin_vbat)) / 4095.0*6.7828; 220 #elif BOARD_MODEL == BOARD_HELTEC_T114 221 float battery_measurement = (float)(analogRead(pin_vbat)) * 0.017165; 222 #elif BOARD_MODEL == BOARD_TECHO 223 float battery_measurement = (float)(analogRead(pin_vbat)) * 0.007067; 224 #else 225 float battery_measurement = (float)(analogRead(pin_vbat)) / 4095.0*7.26; 226 #endif 227 228 bat_v_samples[bat_samples_count%BAT_SAMPLES] = battery_measurement; 229 bat_p_samples[bat_samples_count%BAT_SAMPLES] = ((battery_voltage-BAT_V_MIN) / (BAT_V_MAX-BAT_V_MIN))*100.0; 230 231 bat_samples_count++; 232 if (!battery_ready && bat_samples_count >= BAT_SAMPLES) { 233 battery_ready = true; 234 } 235 236 if (battery_ready) { 237 238 battery_percent = 0; 239 for (uint8_t bi = 0; bi < BAT_SAMPLES; bi++) { 240 battery_percent += bat_p_samples[bi]; 241 } 242 battery_percent = battery_percent/BAT_SAMPLES; 243 244 battery_voltage = 0; 245 for (uint8_t bi = 0; bi < BAT_SAMPLES; bi++) { 246 battery_voltage += bat_v_samples[bi]; 247 } 248 battery_voltage = battery_voltage/BAT_SAMPLES; 249 250 if (bat_delay_v == 0) bat_delay_v = battery_voltage; 251 if (bat_state_change_v == 0) bat_state_change_v = battery_voltage; 252 if (battery_percent > 100.0) battery_percent = 100.0; 253 if (battery_percent < 0.0) battery_percent = 0.0; 254 255 if (bat_samples_count%BAT_SAMPLES == 0) { 256 pmu_sc++; 257 bat_delay_diff = battery_voltage-bat_state_change_v; 258 259 if (battery_voltage < bat_delay_v && battery_voltage < BAT_V_FLOAT) { 260 if (bat_voltage_dropping == false) { 261 if (bat_delay_diff < -0.008) { 262 bat_voltage_dropping = true; 263 bat_state_change_v = battery_voltage; 264 } 265 } else { 266 if (pmu_sc%PMU_SCV_RESET_INTERVAL == 0) { bat_state_change_v = battery_voltage; } 267 } 268 } else { 269 if (bat_voltage_dropping == true) { 270 if (bat_delay_diff > 0.01) { 271 bat_voltage_dropping = false; 272 bat_state_change_v = battery_voltage; 273 } 274 } 275 } 276 bat_samples_count = 0; 277 bat_delay_v = battery_voltage; 278 } 279 280 if (bat_voltage_dropping && battery_voltage < BAT_V_FLOAT) { 281 // if (battery_state != BATTERY_STATE_DISCHARGING) { SerialBT.printf("STATE CHANGE to DISCHARGING at delta=%.3fv. State change v is now %.3fv.\n", bat_delay_diff, bat_state_change_v); } 282 battery_state = BATTERY_STATE_DISCHARGING; 283 pmu_charged_ascertain = 0; 284 } else { 285 if (pmu_charged_ascertain < 8) { pmu_charged_ascertain++; } 286 else { 287 if (battery_percent < 100.0) { 288 // if (battery_state != BATTERY_STATE_CHARGING) { SerialBT.printf("STATE CHANGE to CHARGING at delta=%.3fv. State change v is now %.3fv.\n", bat_delay_diff, bat_state_change_v); } 289 battery_state = BATTERY_STATE_CHARGING; 290 } else { 291 // if (battery_state != BATTERY_STATE_CHARGED) { SerialBT.printf("STATE CHANGE to CHARGED at delta=%.3fv. State change v is now %.3fv.\n", bat_delay_diff, bat_state_change_v); } 292 battery_state = BATTERY_STATE_CHARGED; 293 } 294 } 295 } 296 297 #if MCU_VARIANT == MCU_NRF52 298 if (bt_state != BT_STATE_OFF) { blebas.write(battery_percent); } 299 #endif 300 301 // if (bt_state == BT_STATE_CONNECTED) { 302 // SerialBT.printf("\nBus voltage %.3fv. Unfiltered %.3fv. Diff %.3f", battery_voltage, bat_v_samples[BAT_SAMPLES-1], bat_delay_diff); 303 // if (bat_voltage_dropping) { SerialBT.printf("\n Voltage is dropping. Percentage %.1f%%.", battery_percent); } 304 // else { SerialBT.printf("\n Voltage is not dropping. Percentage %.1f%%.", battery_percent); } 305 // if (battery_state == BATTERY_STATE_DISCHARGING) { SerialBT.printf("\n Battery discharging. delay_v %.3fv\nState change at %.3fv", bat_delay_v, bat_state_change_v); } 306 // if (battery_state == BATTERY_STATE_CHARGING) { SerialBT.printf("\n Battery charging. delay_v %.3fv\nState change at %.3fv", bat_delay_v, bat_state_change_v); } 307 // if (battery_state == BATTERY_STATE_CHARGED) { SerialBT.print("\n Battery is charged."); } 308 // SerialBT.print("\n"); 309 // } 310 } 311 312 #elif BOARD_MODEL == BOARD_TBEAM || BOARD_MODEL == BOARD_TBEAM_S_V1 313 if (PMU) { 314 float discharge_current = 0; 315 float charge_current = 0; 316 float ext_voltage = 0; 317 float ext_current = 0; 318 if (PMU->getChipModel() == XPOWERS_AXP192) { 319 discharge_current = ((XPowersAXP192*)PMU)->getBattDischargeCurrent(); 320 charge_current = ((XPowersAXP192*)PMU)->getBatteryChargeCurrent(); 321 battery_voltage = PMU->getBattVoltage()/1000.0; 322 // battery_percent = PMU->getBattPercentage()*1.0; 323 battery_installed = PMU->isBatteryConnect(); 324 external_power = PMU->isVbusIn(); 325 ext_voltage = PMU->getVbusVoltage()/1000.0; 326 ext_current = ((XPowersAXP192*)PMU)->getVbusCurrent(); 327 } 328 else if (PMU->getChipModel() == XPOWERS_AXP2101) { 329 battery_voltage = PMU->getBattVoltage()/1000.0; 330 // battery_percent = PMU->getBattPercentage()*1.0; 331 battery_installed = PMU->isBatteryConnect(); 332 external_power = PMU->isVbusIn(); 333 ext_voltage = PMU->getVbusVoltage()/1000.0; 334 } 335 336 if (battery_installed) { 337 if (PMU->isCharging()) { 338 battery_state = BATTERY_STATE_CHARGING; 339 battery_percent = ((battery_voltage-BAT_V_MIN) / (BAT_V_MAX-BAT_V_MIN))*100.0; 340 } else { 341 if (PMU->isDischarge()) { 342 battery_state = BATTERY_STATE_DISCHARGING; 343 battery_percent = ((battery_voltage-BAT_V_MIN) / (BAT_V_MAX-BAT_V_MIN))*100.0; 344 } else { 345 battery_state = BATTERY_STATE_CHARGED; 346 battery_percent = 100.0; 347 } 348 } 349 } else { 350 battery_state = BATTERY_STATE_UNKNOWN; 351 battery_percent = 0.0; 352 battery_voltage = 0.0; 353 } 354 355 if (battery_percent > 100.0) battery_percent = 100.0; 356 if (battery_percent < 0.0) battery_percent = 0.0; 357 358 float charge_watts = battery_voltage*(charge_current/1000.0); 359 float discharge_watts = battery_voltage*(discharge_current/1000.0); 360 float ext_watts = ext_voltage*(ext_current/1000.0); 361 362 battery_ready = true; 363 364 // if (bt_state == BT_STATE_CONNECTED) { 365 // if (battery_installed) { 366 // if (external_power) { 367 // SerialBT.printf("External power connected, drawing %.2fw, %.1fmA at %.1fV\n", ext_watts, ext_current, ext_voltage); 368 // } else { 369 // SerialBT.println("Running on battery"); 370 // } 371 // SerialBT.printf("Battery percentage %.1f%%\n", battery_percent); 372 // SerialBT.printf("Battery voltage %.2fv\n", battery_voltage); 373 // // SerialBT.printf("Temperature %.1f%\n", auxillary_temperature); 374 375 // if (battery_state == BATTERY_STATE_CHARGING) { 376 // SerialBT.printf("Charging with %.2fw, %.1fmA at %.1fV\n", charge_watts, charge_current, battery_voltage); 377 // } else if (battery_state == BATTERY_STATE_DISCHARGING) { 378 // SerialBT.printf("Discharging at %.2fw, %.1fmA at %.1fV\n", discharge_watts, discharge_current, battery_voltage); 379 // } else if (battery_state == BATTERY_STATE_CHARGED) { 380 // SerialBT.printf("Battery charged\n"); 381 // } 382 // } else { 383 // SerialBT.println("No battery installed"); 384 // } 385 // SerialBT.println(""); 386 // } 387 } 388 else { 389 battery_ready = false; 390 } 391 #endif 392 393 if (battery_ready) { 394 pmu_rc++; 395 if (pmu_rc%PMU_R_INTERVAL == 0) { 396 kiss_indicate_battery(); 397 if (pmu_temp_sensor_ready) { kiss_indicate_temperature(); } 398 } 399 } 400 } 401 402 void update_pmu() { 403 if (millis()-last_pmu_update >= pmu_update_interval) { 404 measure_battery(); 405 measure_temperature(); 406 last_pmu_update = millis(); 407 } 408 } 409 410 bool init_pmu() { 411 #if IS_ESP32S3 412 pmu_temp_sensor_ready = true; 413 #endif 414 415 #if BOARD_MODEL == BOARD_RNODE_NG_21 || BOARD_MODEL == BOARD_LORA32_V2_1 || BOARD_MODEL == BOARD_TDECK || BOARD_MODEL == BOARD_T3S3 || BOARD_MODEL == BOARD_TECHO 416 pinMode(pin_vbat, INPUT); 417 return true; 418 #elif BOARD_MODEL == BOARD_HELTEC32_V3 419 // there are three version of V3: V3, V3.1, and V3.2 420 // V3 and V3.1 have a pull up on pin_ctrl and are active low 421 // V3.2 has a transistor and active high 422 // put the pin input mode and read it. if it's high, we have V3 or V3.1 423 // other wise, it's a V3.2 424 uint16_t pin_ctrl_value; 425 uint8_t pin_ctrl_active = LOW; 426 pinMode(pin_ctrl, INPUT); 427 pin_ctrl_value = digitalRead(pin_ctrl); 428 if(pin_ctrl_value == HIGH) { 429 // We have either a V3 or V3.1 430 pin_ctrl_active = LOW; 431 } 432 else { 433 // We have a V3.2 434 pin_ctrl_active = HIGH; 435 } 436 pinMode(pin_ctrl,OUTPUT); 437 digitalWrite(pin_ctrl, pin_ctrl_active); 438 return true; 439 #elif BOARD_MODEL == BOARD_HELTEC32_V4 440 pinMode(pin_ctrl,OUTPUT); 441 digitalWrite(pin_ctrl, HIGH); 442 return true; 443 #elif BOARD_MODEL == BOARD_HELTEC_T114 444 pinMode(pin_ctrl,OUTPUT); 445 digitalWrite(pin_ctrl, HIGH); 446 return true; 447 #elif BOARD_MODEL == BOARD_TBEAM 448 Wire.begin(I2C_SDA, I2C_SCL); 449 450 if (!PMU) { 451 PMU = new XPowersAXP2101(PMU_WIRE_PORT); 452 if (!PMU->init()) { 453 delete PMU; 454 PMU = NULL; 455 } 456 } 457 458 if (!PMU) { 459 PMU = new XPowersAXP192(PMU_WIRE_PORT); 460 if (!PMU->init()) { 461 delete PMU; 462 PMU = NULL; 463 } 464 } 465 466 if (!PMU) { 467 return false; 468 } 469 470 // Configure charging indicator 471 PMU->setChargingLedMode(XPOWERS_CHG_LED_OFF); 472 473 pinMode(PMU_IRQ, INPUT_PULLUP); 474 attachInterrupt(PMU_IRQ, setPmuFlag, FALLING); 475 476 if (PMU->getChipModel() == XPOWERS_AXP192) { 477 478 // Turn off unused power sources to save power 479 PMU->disablePowerOutput(XPOWERS_DCDC1); 480 PMU->disablePowerOutput(XPOWERS_DCDC2); 481 PMU->disablePowerOutput(XPOWERS_LDO2); 482 PMU->disablePowerOutput(XPOWERS_LDO3); 483 484 // Set the power of LoRa and GPS module to 3.3V 485 // LoRa 486 PMU->setPowerChannelVoltage(XPOWERS_LDO2, 3300); 487 // GPS 488 PMU->setPowerChannelVoltage(XPOWERS_LDO3, 3300); 489 // OLED 490 PMU->setPowerChannelVoltage(XPOWERS_DCDC1, 3300); 491 492 // Turn on LoRa 493 PMU->enablePowerOutput(XPOWERS_LDO2); 494 495 // Turn on GPS 496 //PMU->enablePowerOutput(XPOWERS_LDO3); 497 498 // protected oled power source 499 PMU->setProtectedChannel(XPOWERS_DCDC1); 500 // protected esp32 power source 501 PMU->setProtectedChannel(XPOWERS_DCDC3); 502 // enable oled power 503 PMU->enablePowerOutput(XPOWERS_DCDC1); 504 505 PMU->disableIRQ(XPOWERS_AXP192_ALL_IRQ); 506 507 PMU->enableIRQ(XPOWERS_AXP192_VBUS_REMOVE_IRQ | 508 XPOWERS_AXP192_VBUS_INSERT_IRQ | 509 XPOWERS_AXP192_BAT_CHG_DONE_IRQ | 510 XPOWERS_AXP192_BAT_CHG_START_IRQ | 511 XPOWERS_AXP192_BAT_REMOVE_IRQ | 512 XPOWERS_AXP192_BAT_INSERT_IRQ | 513 XPOWERS_AXP192_PKEY_SHORT_IRQ 514 ); 515 516 } 517 else if (PMU->getChipModel() == XPOWERS_AXP2101) { 518 519 // Turn off unused power sources to save power 520 PMU->disablePowerOutput(XPOWERS_DCDC2); 521 PMU->disablePowerOutput(XPOWERS_DCDC3); 522 PMU->disablePowerOutput(XPOWERS_DCDC4); 523 PMU->disablePowerOutput(XPOWERS_DCDC5); 524 PMU->disablePowerOutput(XPOWERS_ALDO1); 525 PMU->disablePowerOutput(XPOWERS_ALDO2); 526 PMU->disablePowerOutput(XPOWERS_ALDO3); 527 PMU->disablePowerOutput(XPOWERS_ALDO4); 528 PMU->disablePowerOutput(XPOWERS_BLDO1); 529 PMU->disablePowerOutput(XPOWERS_BLDO2); 530 PMU->disablePowerOutput(XPOWERS_DLDO1); 531 PMU->disablePowerOutput(XPOWERS_DLDO2); 532 PMU->disablePowerOutput(XPOWERS_VBACKUP); 533 534 // Set the power of LoRa and GPS module to 3.3V 535 // LoRa 536 PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300); 537 // GPS 538 PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300); 539 PMU->setPowerChannelVoltage(XPOWERS_VBACKUP, 3300); 540 541 // ESP32 VDD 542 // ! No need to set, automatically open , Don't close it 543 // PMU->setPowerChannelVoltage(XPOWERS_DCDC1, 3300); 544 // PMU->setProtectedChannel(XPOWERS_DCDC1); 545 PMU->setProtectedChannel(XPOWERS_DCDC1); 546 547 // LoRa VDD 548 PMU->enablePowerOutput(XPOWERS_ALDO2); 549 550 // GNSS VDD 551 //PMU->enablePowerOutput(XPOWERS_ALDO3); 552 553 // GNSS RTC PowerVDD 554 //PMU->enablePowerOutput(XPOWERS_VBACKUP); 555 } 556 557 PMU->enableSystemVoltageMeasure(); 558 PMU->enableVbusVoltageMeasure(); 559 PMU->enableBattVoltageMeasure(); 560 // It is necessary to disable the detection function of the TS pin on the board 561 // without the battery temperature detection function, otherwise it will cause abnormal charging 562 PMU->disableTSPinMeasure(); 563 564 // Set the time of pressing the button to turn off 565 PMU->setPowerKeyPressOffTime(XPOWERS_POWEROFF_4S); 566 567 return true; 568 #elif BOARD_MODEL == BOARD_TBEAM_S_V1 569 Wire1.begin(I2C_SDA, I2C_SCL); 570 571 if (!PMU) { 572 PMU = new XPowersAXP2101(PMU_WIRE_PORT); 573 if (!PMU->init()) { 574 delete PMU; 575 PMU = NULL; 576 } 577 } 578 579 if (!PMU) { 580 return false; 581 } 582 583 /** 584 * gnss module power channel 585 * The default ALDO4 is off, you need to turn on the GNSS power first, otherwise it will be invalid during 586 * initialization 587 */ 588 PMU->setPowerChannelVoltage(XPOWERS_ALDO4, 3300); 589 PMU->enablePowerOutput(XPOWERS_ALDO4); 590 591 // lora radio power channel 592 PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300); 593 PMU->enablePowerOutput(XPOWERS_ALDO3); 594 595 // m.2 interface 596 PMU->setPowerChannelVoltage(XPOWERS_DCDC3, 3300); 597 PMU->enablePowerOutput(XPOWERS_DCDC3); 598 599 /** 600 * ALDO2 cannot be turned off. 601 * It is a necessary condition for sensor communication. 602 * It must be turned on to properly access the sensor and screen 603 * It is also responsible for the power supply of PCF8563 604 */ 605 PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300); 606 PMU->enablePowerOutput(XPOWERS_ALDO2); 607 608 // 6-axis , magnetometer ,bme280 , oled screen power channel 609 PMU->setPowerChannelVoltage(XPOWERS_ALDO1, 3300); 610 PMU->enablePowerOutput(XPOWERS_ALDO1); 611 612 // sdcard power channle 613 PMU->setPowerChannelVoltage(XPOWERS_BLDO1, 3300); 614 PMU->enablePowerOutput(XPOWERS_BLDO1); 615 616 // PMU->setPowerChannelVoltage(XPOWERS_DCDC4, 3300); 617 // PMU->enablePowerOutput(XPOWERS_DCDC4); 618 619 // not use channel 620 PMU->disablePowerOutput(XPOWERS_DCDC2); // not elicited 621 PMU->disablePowerOutput(XPOWERS_DCDC5); // not elicited 622 PMU->disablePowerOutput(XPOWERS_DLDO1); // Invalid power channel, it does not exist 623 PMU->disablePowerOutput(XPOWERS_DLDO2); // Invalid power channel, it does not exist 624 PMU->disablePowerOutput(XPOWERS_VBACKUP); 625 626 // Configure charging 627 PMU->setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V2); 628 PMU->setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_500MA); 629 // TODO: Reset 630 PMU->setChargingLedMode(XPOWERS_CHG_LED_CTRL_CHG); 631 632 // Set the time of pressing the button to turn off 633 PMU->setPowerKeyPressOffTime(XPOWERS_POWEROFF_4S); 634 PMU->setPowerKeyPressOnTime(XPOWERS_POWERON_128MS); 635 636 // disable all axp chip interrupt 637 PMU->disableIRQ(XPOWERS_AXP2101_ALL_IRQ); 638 PMU->clearIrqStatus(); 639 640 // It is necessary to disable the detection function of the TS pin on the board 641 // without the battery temperature detection function, otherwise it will cause abnormal charging 642 PMU->disableTSPinMeasure(); 643 PMU->enableVbusVoltageMeasure(); 644 PMU->enableBattVoltageMeasure(); 645 646 647 return true; 648 #else 649 return false; 650 #endif 651 }