123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 |
- #define TWALI_INTERNAL
- #include "twali_system_internal.h"
- #include <stdlib.h>
- extern "C" {
- #define POWER_DOWN_DELAY 11000
- #define SUSPEND_DELAY 15000
- #define SHORT_KEYPRESS_DELAY 200
- struct twali_power {
- uint32_t power_down_delay;
- uint32_t suspend_delay;
-
- struct twali_system * system;
- AXP20X_Class * power;
-
- // state of the system
- int plugged_in;
- int low_power;
- int charging;
- int read_irq;
- long unsigned int now;
- // statistics about the system
- int battery_percentage;
- float battery_current;
- float vbus_current;
- long unsigned int last_logged;
-
- // managing the sleep/low_power/high_power state
- long unsigned int last_touch;
- long unsigned int wake_time;
- long unsigned int sleep_time;
- long unsigned int last_interaction;
-
- };
- static struct twali_power twali_power_singleton;
- static struct twali_power* twali_power_singleton_pointer = NULL;
- struct twali_power * twali_power_make(struct twali_system *s) {
- if (NULL != twali_power_singleton_pointer) {
- return twali_power_singleton_pointer;
- }
- twali_power_singleton.power = s->handle->power;
- twali_power_singleton.power_down_delay = POWER_DOWN_DELAY;
- twali_power_singleton.suspend_delay = SUSPEND_DELAY;
- twali_power_singleton.system = s;
- // state of the system
- twali_power_singleton.plugged_in = 0;
- twali_power_singleton.charging = 0;
- twali_power_singleton.read_irq = 0;
- twali_power_singleton.now = 0;
- // statistics about the system
- twali_power_singleton.battery_percentage = 0;
- twali_power_singleton.battery_current = 0.0;
- twali_power_singleton.vbus_current = 0.0;
- twali_power_singleton.last_logged = 0;
-
- // managing the sleep/low_power/high_power state
- twali_power_singleton.last_touch = 0;
- twali_power_singleton.wake_time = 0;
- twali_power_singleton.sleep_time = 0;
- twali_power_singleton.last_interaction = 0;
- twali_power_singleton.low_power = 0;
- twali_power_singleton_pointer = &twali_power_singleton;
- return twali_power_singleton_pointer;
- }
- void twali_power_interrupt(struct twali_power *p) {
- p->read_irq = 1;
- }
- int twali_power_plugged_in(struct twali_power *p) {
- return p->plugged_in;
- }
- int twali_power_charging(struct twali_power *p) {
- return p->charging;
- }
- int twali_power_low(struct twali_power *p) {
- return p->low_power;
- }
- void twali_power_run(struct twali_power *p);
- int twali_power_battery_percentage(struct twali_power *p) {
- int actual_percentage = p->power->getBattPercentage();
- if (twali_power_plugged_in(p)) {
- if (actual_percentage >= p->battery_percentage) {
- p->battery_percentage = actual_percentage;
- }
- } else {
- if (actual_percentage <= p->battery_percentage) {
- p->battery_percentage = actual_percentage;
- }
- }
- return p->battery_percentage;
- }
- float twali_power_battery_current(struct twali_power *p) {
- return p->battery_current;
- }
- float twali_power_vbus_current(struct twali_power *p) {
- return p->vbus_current;
- }
- float twali_power_last_interaction(struct twali_power *p);
- float twali_power_now(struct twali_power *p);
- void twali_power_up(struct twali_power *p);
- void twali_power_down(struct twali_power *p) {
- printf("%s\n", __func__);
- p->system->handle->closeBL();
- p->system->handle->displaySleep();
- p->low_power = 1;
- p->sleep_time = p->now;
- }
- void twali_power_up(struct twali_power *p) {
- printf("%s\n", __func__);
- p->system->handle->displayWakeup();
- p->system->handle->openBL();
- p->system->tft->fillScreen(TFT_WHITE);
- p->wake_time = p->last_interaction = p->now;
- p->low_power = 0;
- }
- void twali_power_suspend(struct twali_power *p) {
- printf("%s\n", __func__);
- esp_sleep_enable_gpio_wakeup();
- p->system->tft->fillScreen(TFT_BLACK);
- esp_light_sleep_start();
- twali_system_wake_up(p->system);
- printf("%s\n", "back from suspend");
- }
- void twali_power_task(void * object);
- void twali_power_start_task(struct twali_power * p);
- int twali_power_check_touch(struct twali_power *p) {
- if (p->system->handle->touch->touched() > 0) {
- p->last_touch = p->last_interaction = p->now;
- return 1;
- }
- return 0;
- }
- void twali_power_init(struct twali_power *p) {
- p->power->setPowerOutPut(
- AXP202_EXTEN
- | AXP202_DCDC2
- | AXP202_LDO3
- | AXP202_LDO4
- , AXP202_OFF);
- p->power->adc1Enable(
- AXP202_BATT_VOL_ADC1
- | AXP202_BATT_CUR_ADC1
- | AXP202_VBUS_CUR_ADC1
- , AXP202_ON);
- p->power->adc1Enable(
- AXP202_VBUS_VOL_ADC1
- , AXP202_OFF);
- gpio_wakeup_enable((gpio_num_t)AXP202_INT, GPIO_INTR_LOW_LEVEL);
- p->power->enableIRQ(
- AXP202_VBUS_REMOVED_IRQ
- | AXP202_VBUS_CONNECT_IRQ
- | AXP202_CHARGING_IRQ
- | AXP202_CHARGING_FINISHED_IRQ
- | AXP202_PEK_LONGPRESS_IRQ
- | AXP202_PEK_SHORTPRESS_IRQ
- , AXP202_ON);
- p->power->clearIRQ();
- p->plugged_in = p->power->isVBUSPlug();
- p->charging = p->power->isChargeingEnable();
- p->battery_percentage = p->power->getBattPercentage();
- }
- void twali_power_read_irq(struct twali_power *p) {
- p->power->readIRQ();
- p->read_irq = false;
- if (p->power->isVbusPlugInIRQ()) p->plugged_in = 1;
- if (p->power->isVbusRemoveIRQ()) p->plugged_in = 0;
- if (p->power->isChargingIRQ()) p->charging = 0;
- if (p->power->isChargingDoneIRQ()) p->charging = 1;
- if (p->power->isPEKShortPressIRQ()) {
- if (p->now - p->last_interaction > SHORT_KEYPRESS_DELAY) {
- if (p->low_power) twali_power_up(p);
- else twali_power_down(p);
- }
- }
-
- p->power->clearIRQ();
- p->last_interaction = p->now;
- }
- void twali_power_up_try(struct twali_power *p) {
- if (p->last_touch > p->sleep_time) {
- twali_power_up(p);
- }
- }
- void twali_power_down_try(struct twali_power *p) {
- if (p->plugged_in) return;
- if (p->now - p->last_interaction > p->power_down_delay) {
- twali_power_down(p);
- }
- }
- void twali_power_suspend_try(struct twali_power *p) {
- if (p->plugged_in) return;
- if (p->now - p->last_interaction > p->suspend_delay) {
- twali_power_suspend(p);
- }
- }
- void twali_log_power(struct twali_power * p) {
- p->battery_current = (p->battery_current + p->power->getBattDischargeCurrent()) / 2;
- p->vbus_current = (p->vbus_current + p->power->getVbusCurrent()) / 2;
- p->last_logged = p->now;
- }
- void twali_power_run(struct twali_power *p) {
- p->now = millis();
- if (p->read_irq) twali_power_read_irq(p);
- twali_power_check_touch(p);
- if (p->low_power) {
- twali_power_up_try(p);
- if (p->low_power) {
- twali_power_suspend_try(p);
- }
- } else {
- twali_power_down_try(p);
- }
- if (p->now - p->last_logged > 500) {
- twali_log_power(p);
- }
- }
- void twali_power_task(void* object) {
- struct twali_power * p = (struct twali_power *) object;
- twali_power_init(p);
- for (;;) {
- twali_power_run(p);
- vTaskDelay(10 / portTICK_PERIOD_MS);
- }
- printf("deleting the power management task!\n");
- vTaskDelete(NULL);
- }
- void twali_power_start_task(struct twali_power * p) {
- xTaskCreate(twali_power_task, "power_manager", 10000, (void *) p, 30, NULL);
- }
- }
|