From 4245330b88bf4a64e305387fe2cbb51b3a4cbc2c Mon Sep 17 00:00:00 2001 From: "Jamie C. Driver" Date: Fri, 13 Sep 2024 16:46:38 +0100 Subject: [PATCH] v2: update usb detection code for sgm chip --- main/power/jadev20.inc | 83 +++++++++++++++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 13 deletions(-) diff --git a/main/power/jadev20.inc b/main/power/jadev20.inc index f7985493..05fb3d69 100644 --- a/main/power/jadev20.inc +++ b/main/power/jadev20.inc @@ -21,16 +21,30 @@ #define PMIC_REG_BAT_VOLTS_3 0x03 #define PMIC_REG_ADC_0 0x04 #define PMIC_REG_ADC_1 0x05 +#define PMIC_REG_BAT_STATUS 0x06 #define PMIC_REG_POWER_OFF 0x10 #define PMIC_REG_OTG 0x11 #define PMIC_REG_DISABLE_DOWNLOAD 0xF1 #define PMIC_REG_DISABLE_RESET 0xF2 +#define PMIC_REG_FW_VERSION 0xFE -#define LCD_RST (gpio_num_t)46 +#define PMIC_REG_BAT_CHARGING_MASK 0x30 +#define PMIC_REG_BAT_CHARGING 0x10 + +#define SGM7220_ADDR 0x47 +#define SGM7220_REG_TYPE 0x09 + +#define SGM7220_REG_TYPE_SHIFT 6 +#define SGM7220_REG_TYPE_SOURCE 0x01 +#define SGM7220_REG_TYPE_SINK 0x02 + +#define USB_INT_PIN (gpio_num_t)18 + +#ifndef SGM7220_ADDR +// Early dev prototypes had HUSB320 instead of SGM7220 #define HUSB320_ADDR 0x21 #define HUSB320_REG_TYPE 0x13 #define HUSB320_REG_STATUS 0x11 -#define HUSB320_INT_PIN (gpio_num_t)18 #define HUSB320_REG_TYPE_SOURCE 0x08 #define HUSB320_REG_TYPE_HOST_MODE 0x10 @@ -38,6 +52,7 @@ #define HUSB320_REG_STATUS_VBUS_CONNECTED 0x08 #define HUSB320_REG_STATUS_POWER_HIGH 0x04 // 3A #define HUSB320_REG_STATUS_POWER_LOW 0x02 // 1.5A +#endif static SemaphoreHandle_t usb_semaphore; @@ -55,7 +70,24 @@ void usb_detection_task(void* param) while (true) { if (xSemaphoreTake(usb_semaphore, portMAX_DELAY) == pdTRUE) { JADE_SEMAPHORE_TAKE(i2c_mutex); - // reset interrupts +#ifdef SGM7220_ADDR + uint8_t usb_type; + I2C_LOG_ANY_ERROR(_power_master_read_slave(SGM7220_ADDR, SGM7220_REG_TYPE, &usb_type, 1)); + + // Reset interrupts + // The field may be cleared by a write of one. Writing of zeros to the field have no effect. + I2C_LOG_ANY_ERROR(_power_write_command(SGM7220_ADDR, SGM7220_REG_TYPE, (usb_type | (0x1 << 4)))); + + usb_type >>= SGM7220_REG_TYPE_SHIFT; + if (usb_type == SGM7220_REG_TYPE_SOURCE) { + // set to source mode + I2C_LOG_ANY_ERROR(_power_write_command(PMIC_ADDR, PMIC_REG_OTG, 0x01)); + } else if (usb_type == SGM7220_REG_TYPE_SINK) { + // set to sink mode + I2C_LOG_ANY_ERROR(_power_write_command(PMIC_ADDR, PMIC_REG_OTG, 0x00)); + } +#else + // Reset interrupts I2C_LOG_ANY_ERROR(_power_write_command(HUSB320_ADDR, 0x14, 0xff)); I2C_LOG_ANY_ERROR(_power_write_command(HUSB320_ADDR, 0x15, 0xff)); @@ -69,6 +101,7 @@ void usb_detection_task(void* param) // set to sink mode I2C_LOG_ANY_ERROR(_power_write_command(PMIC_ADDR, PMIC_REG_OTG, 0x00)); } +#endif JADE_SEMAPHORE_GIVE(i2c_mutex); } } @@ -95,13 +128,25 @@ esp_err_t power_init(void) usb_semaphore = xSemaphoreCreateBinary(); JADE_ASSERT(usb_semaphore); - // do usb detection for power boost - gpio_set_intr_type(HUSB320_INT_PIN, GPIO_INTR_NEGEDGE); - I2C_CHECK_RET(gpio_install_isr_service(0)); + // Need read twice for some reason - first one always fails, second should work! + uint8_t data; + _power_master_read_slave(PMIC_ADDR, PMIC_REG_FW_VERSION, &data, 1); + I2C_LOG_ANY_ERROR(_power_master_read_slave(PMIC_ADDR, PMIC_REG_FW_VERSION, &data, 1)); + JADE_LOGI("PMIC fw version: %u", data); - gpio_isr_handler_add(HUSB320_INT_PIN, usb_gpio_isr_handler, (void*)HUSB320_INT_PIN); + // Do usb detection for power boost + gpio_set_intr_type(USB_INT_PIN, GPIO_INTR_NEGEDGE); + I2C_CHECK_RET(gpio_install_isr_service(0)); + gpio_isr_handler_add(USB_INT_PIN, usb_gpio_isr_handler, (void*)USB_INT_PIN); + +#ifdef SGM7220_ADDR + uint8_t sgm_id[8] = { 0 }; + I2C_CHECK_RET(_power_master_read_slave(SGM7220_ADDR, 0x00, &sgm_id[0], sizeof(sgm_id))); + JADE_LOGI("SGM7220 Device ID: %02x %02x %02x %02x %02x %02x %02x %02x", sgm_id[7], sgm_id[6], sgm_id[5], sgm_id[4], + sgm_id[3], sgm_id[2], sgm_id[1], sgm_id[0]); + I2C_CHECK_RET(_power_write_command(SGM7220_ADDR, 0x0A, 0x32)); +#else I2C_CHECK_RET(_power_write_command(HUSB320_ADDR, 0x03, 0b01001100)); - uint8_t data; I2C_CHECK_RET(_power_master_read_slave(HUSB320_ADDR, 0x04, &data, 1)); I2C_CHECK_RET(_power_write_command(HUSB320_ADDR, 0x04, data & 0b11111110)); I2C_CHECK_RET(_power_write_command(HUSB320_ADDR, 0x05, 0b111011)); @@ -110,6 +155,7 @@ esp_err_t power_init(void) I2C_CHECK_RET(_power_write_command(HUSB320_ADDR, 0x15, 0xff)); I2C_CHECK_RET(_power_write_command(HUSB320_ADDR, 0x0E, 0b00011011)); I2C_CHECK_RET(_power_write_command(HUSB320_ADDR, 0x0F, 0b00000000)); +#endif const BaseType_t retval = xTaskCreatePinnedToCore( usb_detection_task, "usbdt", 1024 * 4, NULL, JADE_TASK_PRIO_IDLETIMER, NULL, JADE_CORE_GUI); @@ -230,14 +276,13 @@ uint8_t power_get_battery_status(void) bool power_get_battery_charging(void) { - // Connection offers power and battery not fully charged - uint8_t usb_vbus_status; JADE_SEMAPHORE_TAKE(i2c_mutex); - I2C_LOG_ANY_ERROR(_power_master_read_slave(HUSB320_ADDR, HUSB320_REG_STATUS, &usb_vbus_status, 1)); + uint8_t charging_status; + // Bit5-Bit4: 0b00 Ready 0b01 Charging 0b10 Charge done 0b11 Fault + I2C_LOG_ANY_ERROR(_power_master_read_slave(PMIC_ADDR, PMIC_REG_BAT_STATUS, &charging_status, 1)); JADE_SEMAPHORE_GIVE(i2c_mutex); - const bool usb_powered = (usb_vbus_status & (HUSB320_REG_STATUS_POWER_HIGH | HUSB320_REG_STATUS_POWER_LOW)); - return usb_powered && power_get_vbat() < 4100; + return (charging_status & PMIC_REG_BAT_CHARGING_MASK) == PMIC_REG_BAT_CHARGING; } uint16_t power_get_ibat_charge(void) { return 0; } @@ -252,6 +297,17 @@ uint16_t power_get_temp(void) { return 0; } bool usb_connected(void) { +#ifdef SGM7220_ADDR + uint8_t usb_type; + JADE_SEMAPHORE_TAKE(i2c_mutex); + I2C_LOG_ANY_ERROR(_power_master_read_slave(SGM7220_ADDR, SGM7220_REG_TYPE, &usb_type, 1)); + I2C_LOG_ANY_ERROR(_power_write_command(SGM7220_ADDR, SGM7220_REG_TYPE, (usb_type | (0x1 << 4)))); + JADE_SEMAPHORE_GIVE(i2c_mutex); + + // Check we are connected to a usb sink + usb_type >>= SGM7220_REG_TYPE_SHIFT; + return usb_type == SGM7220_REG_TYPE_SINK; +#else uint8_t usb_type, usb_vbus_status; JADE_SEMAPHORE_TAKE(i2c_mutex); I2C_LOG_ANY_ERROR(_power_master_read_slave(HUSB320_ADDR, HUSB320_REG_TYPE, &usb_type, 1)); @@ -261,4 +317,5 @@ bool usb_connected(void) // Check we are 'vbus-connected' to a usb host return ((usb_type & HUSB320_REG_TYPE_HOST_MODE) == HUSB320_REG_TYPE_HOST_MODE) && ((usb_vbus_status & HUSB320_REG_STATUS_VBUS_CONNECTED) == HUSB320_REG_STATUS_VBUS_CONNECTED); +#endif }