diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild index 915b411f..4cfcad7f 100644 --- a/main/Kconfig.projbuild +++ b/main/Kconfig.projbuild @@ -131,7 +131,14 @@ menu "Blockstream Jade" default n help Jade v1 (and some other devices) come with the AXP192 to manage power to ESP, display, camera - + + config HAS_BATTERY + bool "Use analog input as battery level indicator and USB connection" + depends on BOARD_TYPE_TTGO_TDISPLAYS3 + default n + help + Some devices can measure voltage and detect charging status through an analog input. + menu "SDA/SCL Pin Mapping" visible if BOARD_TYPE_CUSTOM diff --git a/main/power.c b/main/power.c index 59ca2a9d..eb88f94c 100644 --- a/main/power.c +++ b/main/power.c @@ -24,6 +24,9 @@ #include "power/twatchs3.inc" #elif defined(CONFIG_HAS_IP5306) #include "power/ip5306.inc" +// ttgo-tdisplays3 can read battery level and charging status if a battery is connected +#elif defined(CONFIG_BOARD_TYPE_TTGO_TDISPLAYS3) && defined(CONFIG_HAS_BATTERY) +#include "power/tdisplays3.inc" #else // Stubs for other hw boards (ie. no power management) #include "power/minimal.inc" diff --git a/main/power/tdisplays3.inc b/main/power/tdisplays3.inc new file mode 100644 index 00000000..88b979fc --- /dev/null +++ b/main/power/tdisplays3.inc @@ -0,0 +1,95 @@ +// tdisplays3 and devices with no power-management but it can measure voltage level of the battery and +// detect charging status when a battery is connected through an analog input +// +#include +#include +#include + +#define BATTERY_ADC_CHANNEL ADC_CHANNEL_3 + +static adc_oneshot_unit_handle_t adc1_handle = NULL; +static adc_cali_handle_t adc1_cali_handle = NULL; + +esp_err_t power_init(void) +{ + // Initialise the ADC to measure battery level + adc_oneshot_unit_init_cfg_t init_config1 = { + .unit_id = ADC_UNIT_1, + }; + ESP_ERROR_CHECK(adc_oneshot_new_unit(&init_config1, &adc1_handle)); + JADE_ASSERT(adc1_handle); + // ADC Config + adc_oneshot_chan_cfg_t config = { + .atten = ADC_ATTEN_DB_12, + .bitwidth = ADC_BITWIDTH_DEFAULT, + }; + ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, BATTERY_ADC_CHANNEL, &config)); + // Curve fitting calibration + adc_cali_curve_fitting_config_t cali_config = { + .unit_id = ADC_UNIT_1, + .atten = ADC_ATTEN_DB_12, + .bitwidth = ADC_BITWIDTH_DEFAULT, + }; + ESP_ERROR_CHECK(adc_cali_create_scheme_curve_fitting(&cali_config, &adc1_cali_handle)); + return ESP_OK; +} + +esp_err_t power_shutdown(void) { return ESP_OK; } +esp_err_t power_screen_on(void) { return ESP_OK; } +esp_err_t power_backlight_on(const uint8_t brightness) { return ESP_OK; } +esp_err_t power_backlight_off(void) { return ESP_OK; } +esp_err_t power_camera_on(void) { return ESP_OK; } +esp_err_t power_camera_off(void) { return ESP_OK; } + +uint16_t power_get_vbat(void) +{ + JADE_ASSERT(adc1_handle); + int cal_vbat = 0; + int raw_vbat = 0; + ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, BATTERY_ADC_CHANNEL, &raw_vbat)); + ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc1_cali_handle, raw_vbat, &cal_vbat)); + return (uint16_t)(cal_vbat * 2); +} +uint8_t power_get_battery_status(void) +{ + const uint16_t vbat = power_get_vbat(); + + if (vbat > 4000) { + return 5; + } else if (vbat > 3800) { + return 4; + } else if (vbat > 3600) { + return 3; + } else if (vbat > 3400) { + return 2; + } else if (vbat > 3200) { + return 1; + } + return 0; +} + +bool power_get_battery_charging(void) +{ + uint16_t vbat = power_get_vbat(); + // If the voltage is greater than 4500 mV and less than 4750 it means its charging + if (vbat > 4500 && vbat < 4750) { + return true; + } + return false; +} + +uint16_t power_get_ibat_charge(void) { return 0; } +uint16_t power_get_ibat_discharge(void) { return 0; } +uint16_t power_get_vusb(void) { return 0; } +uint16_t power_get_iusb(void) { return 0; } +uint16_t power_get_temp(void) { return 0; } + +bool usb_connected(void) +{ + // If the voltage is greater than 4500 mV it means USB is connected + uint16_t vbat = power_get_vbat(); + if (vbat > 4500) { + return true; + } + return false; +}