diff --git a/src/esp32/main-esp32.cpp b/src/esp32/main-esp32.cpp index e04231568..76999cc82 100644 --- a/src/esp32/main-esp32.cpp +++ b/src/esp32/main-esp32.cpp @@ -55,4 +55,171 @@ void setBluetoothEnable(bool on) void getMacAddr(uint8_t *dmac) { assert(esp_efuse_mac_get_default(dmac) == ESP_OK); +} + +#ifdef TBEAM_V10 +/// Reads power status to powerStatus singleton. +// +// TODO(girts): move this and other axp stuff to power.h/power.cpp. +void readPowerStatus() +{ + powerStatus.haveBattery = axp.isBatteryConnect(); + if (powerStatus.haveBattery) { + powerStatus.batteryVoltageMv = axp.getBattVoltage(); + } + powerStatus.usb = axp.isVBUSPlug(); + powerStatus.charging = axp.isChargeing(); +} +#endif // TBEAM_V10 + +#ifdef AXP192_SLAVE_ADDRESS +/** + * Init the power manager chip + * + * axp192 power + DCDC1 0.7-3.5V @ 1200mA max -> OLED // If you turn this off you'll lose comms to the axp192 because the OLED and the axp192 + share the same i2c bus, instead use ssd1306 sleep mode DCDC2 -> unused DCDC3 0.7-3.5V @ 700mA max -> ESP32 (keep this on!) LDO1 + 30mA -> charges GPS backup battery // charges the tiny J13 battery by the GPS to power the GPS ram (for a couple of days), can + not be turned off LDO2 200mA -> LORA LDO3 200mA -> GPS + */ +void axp192Init() +{ + if (axp192_found) { + if (!axp.begin(Wire, AXP192_SLAVE_ADDRESS)) { + DEBUG_MSG("AXP192 Begin PASS\n"); + + // axp.setChgLEDMode(LED_BLINK_4HZ); + DEBUG_MSG("DCDC1: %s\n", axp.isDCDC1Enable() ? "ENABLE" : "DISABLE"); + DEBUG_MSG("DCDC2: %s\n", axp.isDCDC2Enable() ? "ENABLE" : "DISABLE"); + DEBUG_MSG("LDO2: %s\n", axp.isLDO2Enable() ? "ENABLE" : "DISABLE"); + DEBUG_MSG("LDO3: %s\n", axp.isLDO3Enable() ? "ENABLE" : "DISABLE"); + DEBUG_MSG("DCDC3: %s\n", axp.isDCDC3Enable() ? "ENABLE" : "DISABLE"); + DEBUG_MSG("Exten: %s\n", axp.isExtenEnable() ? "ENABLE" : "DISABLE"); + DEBUG_MSG("----------------------------------------\n"); + + axp.setPowerOutPut(AXP192_LDO2, AXP202_ON); // LORA radio + axp.setPowerOutPut(AXP192_LDO3, AXP202_ON); // GPS main power + axp.setPowerOutPut(AXP192_DCDC2, AXP202_ON); + axp.setPowerOutPut(AXP192_EXTEN, AXP202_ON); + axp.setPowerOutPut(AXP192_DCDC1, AXP202_ON); + axp.setDCDC1Voltage(3300); // for the OLED power + + DEBUG_MSG("DCDC1: %s\n", axp.isDCDC1Enable() ? "ENABLE" : "DISABLE"); + DEBUG_MSG("DCDC2: %s\n", axp.isDCDC2Enable() ? "ENABLE" : "DISABLE"); + DEBUG_MSG("LDO2: %s\n", axp.isLDO2Enable() ? "ENABLE" : "DISABLE"); + DEBUG_MSG("LDO3: %s\n", axp.isLDO3Enable() ? "ENABLE" : "DISABLE"); + DEBUG_MSG("DCDC3: %s\n", axp.isDCDC3Enable() ? "ENABLE" : "DISABLE"); + DEBUG_MSG("Exten: %s\n", axp.isExtenEnable() ? "ENABLE" : "DISABLE"); + +#if 0 + // cribbing from https://github.com/m5stack/M5StickC/blob/master/src/AXP192.cpp to fix charger to be more like 300ms. + // I finally found an english datasheet. Will look at this later - but suffice it to say the default code from TTGO has 'issues' + + axp.adc1Enable(0xff, 1); // turn on all adcs + uint8_t val = 0xc2; + axp._writeByte(0x33, 1, &val); // Bat charge voltage to 4.2, Current 280mA + val = 0b11110010; + // Set ADC sample rate to 200hz + // axp._writeByte(0x84, 1, &val); + + // Not connected + //val = 0xfc; + //axp._writeByte(AXP202_VHTF_CHGSET, 1, &val); // Set temperature protection + + //not used + //val = 0x46; + //axp._writeByte(AXP202_OFF_CTL, 1, &val); // enable bat detection +#endif + axp.debugCharging(); + +#ifdef PMU_IRQ + pinMode(PMU_IRQ, INPUT); + attachInterrupt( + PMU_IRQ, [] { pmu_irq = true; }, FALLING); + + axp.adc1Enable(AXP202_BATT_CUR_ADC1, 1); + axp.enableIRQ(AXP202_BATT_REMOVED_IRQ | AXP202_BATT_CONNECT_IRQ | AXP202_CHARGING_FINISHED_IRQ | AXP202_CHARGING_IRQ | + AXP202_VBUS_REMOVED_IRQ | AXP202_VBUS_CONNECT_IRQ | AXP202_PEK_SHORTPRESS_IRQ, + 1); + + axp.clearIRQ(); +#endif + readPowerStatus(); + } else { + DEBUG_MSG("AXP192 Begin FAIL\n"); + } + } else { + DEBUG_MSG("AXP192 not found\n"); + } +} +#endif + +void esp32Setup() +{ +#ifdef AXP192_SLAVE_ADDRESS + axp192Init(); +#endif +} + +#if 0 +// Turn off for now + +uint32_t axpDebugRead() +{ + axp.debugCharging(); + DEBUG_MSG("vbus current %f\n", axp.getVbusCurrent()); + DEBUG_MSG("charge current %f\n", axp.getBattChargeCurrent()); + DEBUG_MSG("bat voltage %f\n", axp.getBattVoltage()); + DEBUG_MSG("batt pct %d\n", axp.getBattPercentage()); + DEBUG_MSG("is battery connected %d\n", axp.isBatteryConnect()); + DEBUG_MSG("is USB connected %d\n", axp.isVBUSPlug()); + DEBUG_MSG("is charging %d\n", axp.isChargeing()); + + return 30 * 1000; +} + +Periodic axpDebugOutput(axpDebugRead); +#endif + +/// loop code specific to ESP32 targets +void esp32Loop() +{ + loopBLE(); + + // for debug printing + // radio.radioIf.canSleep(); + +#ifdef PMU_IRQ + if (pmu_irq) { + pmu_irq = false; + axp.readIRQ(); + + DEBUG_MSG("pmu irq!\n"); + + if (axp.isChargingIRQ()) { + DEBUG_MSG("Battery start charging\n"); + } + if (axp.isChargingDoneIRQ()) { + DEBUG_MSG("Battery fully charged\n"); + } + if (axp.isVbusRemoveIRQ()) { + DEBUG_MSG("USB unplugged\n"); + } + if (axp.isVbusPlugInIRQ()) { + DEBUG_MSG("USB plugged In\n"); + } + if (axp.isBattPlugInIRQ()) { + DEBUG_MSG("Battery inserted\n"); + } + if (axp.isBattRemoveIRQ()) { + DEBUG_MSG("Battery removed\n"); + } + if (axp.isPEKShortPressIRQ()) { + DEBUG_MSG("PEK short button press\n"); + } + + readPowerStatus(); + axp.clearIRQ(); + } +#endif // T_BEAM_V10 } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 0737e4df5..4ed5e9a8b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -96,103 +96,6 @@ void scanI2Cdevice(void) DEBUG_MSG("done\n"); } -#ifdef TBEAM_V10 -/// Reads power status to powerStatus singleton. -// -// TODO(girts): move this and other axp stuff to power.h/power.cpp. -void readPowerStatus() -{ - powerStatus.haveBattery = axp.isBatteryConnect(); - if (powerStatus.haveBattery) { - powerStatus.batteryVoltageMv = axp.getBattVoltage(); - } - powerStatus.usb = axp.isVBUSPlug(); - powerStatus.charging = axp.isChargeing(); -} -#endif // TBEAM_V10 - -/** - * Init the power manager chip - * - * axp192 power - DCDC1 0.7-3.5V @ 1200mA max -> OLED // If you turn this off you'll lose comms to the axp192 because the OLED and the axp192 - share the same i2c bus, instead use ssd1306 sleep mode DCDC2 -> unused DCDC3 0.7-3.5V @ 700mA max -> ESP32 (keep this on!) LDO1 - 30mA -> charges GPS backup battery // charges the tiny J13 battery by the GPS to power the GPS ram (for a couple of days), can - not be turned off LDO2 200mA -> LORA LDO3 200mA -> GPS - */ -void axp192Init() -{ -#ifdef TBEAM_V10 - if (axp192_found) { - if (!axp.begin(Wire, AXP192_SLAVE_ADDRESS)) { - DEBUG_MSG("AXP192 Begin PASS\n"); - - // axp.setChgLEDMode(LED_BLINK_4HZ); - DEBUG_MSG("DCDC1: %s\n", axp.isDCDC1Enable() ? "ENABLE" : "DISABLE"); - DEBUG_MSG("DCDC2: %s\n", axp.isDCDC2Enable() ? "ENABLE" : "DISABLE"); - DEBUG_MSG("LDO2: %s\n", axp.isLDO2Enable() ? "ENABLE" : "DISABLE"); - DEBUG_MSG("LDO3: %s\n", axp.isLDO3Enable() ? "ENABLE" : "DISABLE"); - DEBUG_MSG("DCDC3: %s\n", axp.isDCDC3Enable() ? "ENABLE" : "DISABLE"); - DEBUG_MSG("Exten: %s\n", axp.isExtenEnable() ? "ENABLE" : "DISABLE"); - DEBUG_MSG("----------------------------------------\n"); - - axp.setPowerOutPut(AXP192_LDO2, AXP202_ON); // LORA radio - axp.setPowerOutPut(AXP192_LDO3, AXP202_ON); // GPS main power - axp.setPowerOutPut(AXP192_DCDC2, AXP202_ON); - axp.setPowerOutPut(AXP192_EXTEN, AXP202_ON); - axp.setPowerOutPut(AXP192_DCDC1, AXP202_ON); - axp.setDCDC1Voltage(3300); // for the OLED power - - DEBUG_MSG("DCDC1: %s\n", axp.isDCDC1Enable() ? "ENABLE" : "DISABLE"); - DEBUG_MSG("DCDC2: %s\n", axp.isDCDC2Enable() ? "ENABLE" : "DISABLE"); - DEBUG_MSG("LDO2: %s\n", axp.isLDO2Enable() ? "ENABLE" : "DISABLE"); - DEBUG_MSG("LDO3: %s\n", axp.isLDO3Enable() ? "ENABLE" : "DISABLE"); - DEBUG_MSG("DCDC3: %s\n", axp.isDCDC3Enable() ? "ENABLE" : "DISABLE"); - DEBUG_MSG("Exten: %s\n", axp.isExtenEnable() ? "ENABLE" : "DISABLE"); - -#if 0 - // cribbing from https://github.com/m5stack/M5StickC/blob/master/src/AXP192.cpp to fix charger to be more like 300ms. - // I finally found an english datasheet. Will look at this later - but suffice it to say the default code from TTGO has 'issues' - - axp.adc1Enable(0xff, 1); // turn on all adcs - uint8_t val = 0xc2; - axp._writeByte(0x33, 1, &val); // Bat charge voltage to 4.2, Current 280mA - val = 0b11110010; - // Set ADC sample rate to 200hz - // axp._writeByte(0x84, 1, &val); - - // Not connected - //val = 0xfc; - //axp._writeByte(AXP202_VHTF_CHGSET, 1, &val); // Set temperature protection - - //not used - //val = 0x46; - //axp._writeByte(AXP202_OFF_CTL, 1, &val); // enable bat detection -#endif - axp.debugCharging(); - -#ifdef PMU_IRQ - pinMode(PMU_IRQ, INPUT); - attachInterrupt( - PMU_IRQ, [] { pmu_irq = true; }, FALLING); - - axp.adc1Enable(AXP202_BATT_CUR_ADC1, 1); - axp.enableIRQ(AXP202_BATT_REMOVED_IRQ | AXP202_BATT_CONNECT_IRQ | AXP202_CHARGING_FINISHED_IRQ | AXP202_CHARGING_IRQ | - AXP202_VBUS_REMOVED_IRQ | AXP202_VBUS_CONNECT_IRQ | AXP202_PEK_SHORTPRESS_IRQ, - 1); - - axp.clearIRQ(); -#endif - readPowerStatus(); - } else { - DEBUG_MSG("AXP192 Begin FAIL\n"); - } - } else { - DEBUG_MSG("AXP192 not found\n"); - } -#endif -} - const char *getDeviceName() { uint8_t dmac[6]; @@ -214,7 +117,7 @@ void setup() #ifdef USE_SEGGER SEGGER_RTT_ConfigUpBuffer(0, NULL, NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_TRIM); #endif - + // Debug #ifdef DEBUG_PORT DEBUG_PORT.begin(SERIAL_BAUD); @@ -256,14 +159,14 @@ void setup() // Don't init display if we don't have one or we are waking headless due to a timer event if (wakeCause == ESP_SLEEP_WAKEUP_TIMER) ssd1306_found = false; // forget we even have the hardware + + esp32Setup(); #endif // Initialize the screen first so we can show the logo while we start up everything else. if (ssd1306_found) screen.setup(); - axp192Init(); - screen.print("Started...\n"); // Init GPS @@ -298,26 +201,6 @@ uint32_t ledBlinker() Periodic ledPeriodic(ledBlinker); -#if 0 -// Turn off for now - -uint32_t axpDebugRead() -{ - axp.debugCharging(); - DEBUG_MSG("vbus current %f\n", axp.getVbusCurrent()); - DEBUG_MSG("charge current %f\n", axp.getBattChargeCurrent()); - DEBUG_MSG("bat voltage %f\n", axp.getBattVoltage()); - DEBUG_MSG("batt pct %d\n", axp.getBattPercentage()); - DEBUG_MSG("is battery connected %d\n", axp.isBatteryConnect()); - DEBUG_MSG("is USB connected %d\n", axp.isVBUSPlug()); - DEBUG_MSG("is charging %d\n", axp.isChargeing()); - - return 30 * 1000; -} - -Periodic axpDebugOutput(axpDebugRead); -#endif - void loop() { uint32_t msecstosleep = 1000 * 30; // How long can we sleep before we again need to service the main loop? @@ -331,46 +214,9 @@ void loop() // axpDebugOutput.loop(); #ifndef NO_ESP32 - loopBLE(); + esp32Loop(); #endif - // for debug printing - // radio.radioIf.canSleep(); - -#ifdef PMU_IRQ - if (pmu_irq) { - pmu_irq = false; - axp.readIRQ(); - - DEBUG_MSG("pmu irq!\n"); - - if (axp.isChargingIRQ()) { - DEBUG_MSG("Battery start charging\n"); - } - if (axp.isChargingDoneIRQ()) { - DEBUG_MSG("Battery fully charged\n"); - } - if (axp.isVbusRemoveIRQ()) { - DEBUG_MSG("USB unplugged\n"); - } - if (axp.isVbusPlugInIRQ()) { - DEBUG_MSG("USB plugged In\n"); - } - if (axp.isBattPlugInIRQ()) { - DEBUG_MSG("Battery inserted\n"); - } - if (axp.isBattRemoveIRQ()) { - DEBUG_MSG("Battery removed\n"); - } - if (axp.isPEKShortPressIRQ()) { - DEBUG_MSG("PEK short button press\n"); - } - - readPowerStatus(); - axp.clearIRQ(); - } -#endif // T_BEAM_V10 - #ifdef BUTTON_PIN // if user presses button for more than 3 secs, discard our network prefs and reboot (FIXME, use a debounce lib instead of // this boilerplate)