Skip to content

Commit

Permalink
v2: update usb detection code for sgm chip
Browse files Browse the repository at this point in the history
  • Loading branch information
JamieDriver committed Sep 13, 2024
1 parent 33f16ff commit 4245330
Showing 1 changed file with 70 additions and 13 deletions.
83 changes: 70 additions & 13 deletions main/power/jadev20.inc
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,38 @@
#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

#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;

Expand All @@ -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));

Expand All @@ -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);
}
}
Expand All @@ -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));
Expand All @@ -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);
Expand Down Expand Up @@ -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; }
Expand All @@ -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));
Expand All @@ -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
}

0 comments on commit 4245330

Please sign in to comment.