Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
278 changes: 202 additions & 76 deletions firmware_c5/sdkconfig

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion firmware_p4/components/Core/kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#include "pin_def.h"
#include "st7789.h"
#include "bq25896.h"
#include "driver/i2c.h"
#include "driver/i2c_master.h"
#include "nvs_flash.h"
#include "wifi_service.h"
#include "storage_init.h"
Expand Down
204 changes: 114 additions & 90 deletions firmware_p4/components/Drivers/bq25896/bq25896.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,154 +12,178 @@
// See the License for the specific language governing permissions and
// limitations under the License.


#include "bq25896.h"
#include "driver/i2c.h"
#include "driver/i2c_master.h"
#include "esp_log.h"
#include "i2c_init.h"
#include <string.h>

#define I2C_PORT I2C_NUM_0
#define I2C_MASTER_TIMEOUT_MS 100

// Endereço I2C do BQ25896
#define BQ25896_I2C_ADDR 0x6B

// Definições dos Registradores
#define REG_ILIM 0x00
#define REG_VINDPM 0x01
#define REG_ADC_CTRL 0x02
#define REG_CHG_CTRL_0 0x03
#define REG_ICHG 0x04
#define REG_IPRE_ITERM 0x05
#define REG_VREG 0x06
#define REG_CHG_CTRL_1 0x07
#define REG_CHG_TIMER 0x08
#define REG_BAT_COMP 0x09
#define REG_CHG_CTRL_2 0x0A
#define REG_STATUS 0x0B
#define REG_FAULT 0x0C
#define REG_VINDPM_OS 0x0D
#define REG_BAT_VOLT 0x0E
#define REG_SYS_VOLT 0x0F
#define REG_TS_ADC 0x10
#define REG_VBUS_ADC 0x11
#define REG_ICHG_ADC 0x12
#define REG_IDPM_ADC 0x13
#define REG_CTRL_3 0x14
#define REG_ILIM 0x00
#define REG_VINDPM 0x01
#define REG_ADC_CTRL 0x02
#define REG_CHG_CTRL_0 0x03
#define REG_ICHG 0x04
#define REG_IPRE_ITERM 0x05
#define REG_VREG 0x06
#define REG_CHG_CTRL_1 0x07
#define REG_CHG_TIMER 0x08
#define REG_BAT_COMP 0x09
#define REG_CHG_CTRL_2 0x0A
#define REG_STATUS 0x0B
#define REG_FAULT 0x0C
#define REG_VINDPM_OS 0x0D
#define REG_BAT_VOLT 0x0E
#define REG_SYS_VOLT 0x0F
#define REG_TS_ADC 0x10
#define REG_VBUS_ADC 0x11
#define REG_ICHG_ADC 0x12
#define REG_IDPM_ADC 0x13
#define REG_CTRL_3 0x14

// Máscaras para o Registrador de Status (0x0B)
#define STATUS_VBUS_STAT_MASK 0b11100000
#define STATUS_VBUS_STAT_MASK 0b11100000
#define STATUS_VBUS_STAT_SHIFT 5
#define STATUS_CHG_STAT_MASK 0b00011000
#define STATUS_CHG_STAT_SHIFT 3
#define STATUS_PG_STAT_MASK 0b00000100
#define STATUS_PG_STAT_SHIFT 2
#define STATUS_VSYS_STAT_MASK 0b00000001
#define STATUS_CHG_STAT_MASK 0b00011000
#define STATUS_CHG_STAT_SHIFT 3
#define STATUS_PG_STAT_MASK 0b00000100
#define STATUS_PG_STAT_SHIFT 2
#define STATUS_VSYS_STAT_MASK 0b00000001

// Máscaras do ADC (0x02)
#define ADC_CTRL_CONV_RATE_MASK 0b10000000
#define ADC_CTRL_ADC_EN_MASK 0b01000000
#define ADC_CTRL_ADC_EN_MASK 0b01000000

// Máscara para tensão da bateria
#define BATV_MASK 0b01111111

static const char *TAG = "BQ25896";
static i2c_master_dev_handle_t bq25896_dev_handle = NULL;

static esp_err_t bq25896_ensure_device(void) {
if (bq25896_dev_handle != NULL)
return ESP_OK;

i2c_master_bus_handle_t bus = i2c_get_bus_handle();
if (bus == NULL) {
ESP_LOGE(TAG, "I2C bus não inicializado.");
return ESP_ERR_INVALID_STATE;
}

i2c_device_config_t dev_cfg = {
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
.device_address = BQ25896_I2C_ADDR,
.scl_speed_hz = 400000,
};
return i2c_master_bus_add_device(bus, &dev_cfg, &bq25896_dev_handle);
}

// Leitura de registrador
static esp_err_t bq25896_read_reg(uint8_t reg, uint8_t *data) {
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (BQ25896_I2C_ADDR << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, reg, true);
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (BQ25896_I2C_ADDR << 1) | I2C_MASTER_READ, true);
i2c_master_read_byte(cmd, data, I2C_MASTER_LAST_NACK);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(I2C_PORT, cmd, 100 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
esp_err_t ret = bq25896_ensure_device();
if (ret != ESP_OK)
return ret;

return i2c_master_transmit_receive(bq25896_dev_handle, &reg, 1, data, 1,
I2C_MASTER_TIMEOUT_MS);
}

// Escrita de registrador
static esp_err_t bq25896_write_reg(uint8_t reg, uint8_t data) {
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (BQ25896_I2C_ADDR << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, reg, true);
i2c_master_write_byte(cmd, data, true);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(I2C_PORT, cmd, 100 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
esp_err_t ret = bq25896_ensure_device();
if (ret != ESP_OK)
return ret;

uint8_t buf[2] = {reg, data};
return i2c_master_transmit(bq25896_dev_handle, buf, sizeof(buf),
I2C_MASTER_TIMEOUT_MS);
}

// Inicializa o BQ25896
esp_err_t bq25896_init(void) {
uint8_t data;
esp_err_t ret = bq25896_read_reg(REG_CTRL_3, &data);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Falha ao comunicar com o BQ25896.");
return ret;
}
esp_err_t ret = bq25896_ensure_device();
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Falha ao registrar BQ25896 no bus: %s",
esp_err_to_name(ret));
return ret;
}

ret = bq25896_read_reg(REG_ADC_CTRL, &data);
if (ret != ESP_OK) return ret;
uint8_t data;
ret = bq25896_read_reg(REG_CTRL_3, &data);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Falha ao comunicar com o BQ25896.");
return ret;
}

data |= ADC_CTRL_ADC_EN_MASK;
data &= ~ADC_CTRL_CONV_RATE_MASK;
ret = bq25896_read_reg(REG_ADC_CTRL, &data);
if (ret != ESP_OK)
return ret;

ret = bq25896_write_reg(REG_ADC_CTRL, data);
data |= ADC_CTRL_ADC_EN_MASK;
data &= ~ADC_CTRL_CONV_RATE_MASK;

if (ret == ESP_OK) {
ESP_LOGI(TAG, "BQ25896 inicializado com sucesso.");
}
ret = bq25896_write_reg(REG_ADC_CTRL, data);

return ret;
if (ret == ESP_OK) {
ESP_LOGI(TAG, "BQ25896 inicializado com sucesso.");
}

return ret;
}

// Retorna status de carregamento
bq25896_charge_status_t bq25896_get_charge_status(void) {
uint8_t data = 0;
if (bq25896_read_reg(REG_STATUS, &data) == ESP_OK) {
uint8_t status = (data & STATUS_CHG_STAT_MASK) >> STATUS_CHG_STAT_SHIFT;
return (bq25896_charge_status_t)status;
}
return CHARGE_STATUS_NOT_CHARGING;
uint8_t data = 0;
if (bq25896_read_reg(REG_STATUS, &data) == ESP_OK) {
uint8_t status = (data & STATUS_CHG_STAT_MASK) >> STATUS_CHG_STAT_SHIFT;
return (bq25896_charge_status_t)status;
}
return CHARGE_STATUS_NOT_CHARGING;
}

// Retorna status do VBUS
bq25896_vbus_status_t bq25896_get_vbus_status(void) {
uint8_t data = 0;
if (bq25896_read_reg(REG_STATUS, &data) == ESP_OK) {
uint8_t status = (data & STATUS_VBUS_STAT_MASK) >> STATUS_VBUS_STAT_SHIFT;
return (bq25896_vbus_status_t)status;
}
return VBUS_STATUS_UNKNOWN;
uint8_t data = 0;
if (bq25896_read_reg(REG_STATUS, &data) == ESP_OK) {
uint8_t status = (data & STATUS_VBUS_STAT_MASK) >> STATUS_VBUS_STAT_SHIFT;
return (bq25896_vbus_status_t)status;
}
return VBUS_STATUS_UNKNOWN;
}

// Verifica se está carregando
bool bq25896_is_charging(void) {
bq25896_charge_status_t status = bq25896_get_charge_status();
return (status == CHARGE_STATUS_PRECHARGE || status == CHARGE_STATUS_FAST_CHARGE);
bq25896_charge_status_t status = bq25896_get_charge_status();
return (status == CHARGE_STATUS_PRECHARGE ||
status == CHARGE_STATUS_FAST_CHARGE);
}

// Calcula porcentagem estimada da bateria
int bq25896_get_battery_percentage(uint16_t voltage_mv) {
const int min_voltage = 3200; // 0%
const int max_voltage = 4200; // 100%
const int min_voltage = 3200; // 0%
const int max_voltage = 4200; // 100%

if (voltage_mv <= min_voltage) return 0;
if (voltage_mv >= max_voltage) return 100;
if (voltage_mv <= min_voltage)
return 0;
if (voltage_mv >= max_voltage)
return 100;

int percentage = ((voltage_mv - min_voltage) * 100) / (max_voltage - min_voltage);
return percentage > 100 ? 100 : percentage;
int percentage =
((voltage_mv - min_voltage) * 100) / (max_voltage - min_voltage);
return percentage > 100 ? 100 : percentage;
}

// Retorna tensão da bateria
uint16_t bq25896_get_battery_voltage(void) {
uint8_t data = 0;
if (bq25896_read_reg(REG_BAT_VOLT, &data) == ESP_OK) {
uint16_t voltage = 2304 + ((data & BATV_MASK) * 20);
return voltage;
}
return 0;
uint8_t data = 0;
if (bq25896_read_reg(REG_BAT_VOLT, &data) == ESP_OK) {
uint16_t voltage = 2304 + ((data & BATV_MASK) * 20);
return voltage;
}
return 0;
}
2 changes: 1 addition & 1 deletion firmware_p4/components/Drivers/bq25896/include/bq25896.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#ifndef BQ25896_H
#define BQ25896_H

#include "driver/i2c.h"
#include "driver/i2c_master.h"
#include <stdint.h>
#include <stdbool.h>

Expand Down
37 changes: 21 additions & 16 deletions firmware_p4/components/Drivers/i2c_init/i2c_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,37 @@
// limitations under the License.


#include "driver/i2c.h"
#include "driver/i2c_master.h"
#include "esp_log.h"
#include "i2c_init.h"

#define TAG "I2CInit"

static i2c_master_bus_handle_t global_bus_handle = NULL;

void init_i2c(void) {
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
if (global_bus_handle != NULL) {
ESP_LOGI(TAG, "I2C bus já está inicializado.");
return;
}

i2c_master_bus_config_t bus_config = {
.i2c_port = I2C_NUM_0,
.sda_io_num = 8,
.scl_io_num = 9,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = 400000, // 400 kHz
.clk_source = I2C_CLK_SRC_DEFAULT,
.glitch_ignore_cnt = 7,
.flags.enable_internal_pullup = true,
};

esp_err_t ret = i2c_param_config(I2C_NUM_0, &conf);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Erro em i2c_param_config: %s", esp_err_to_name(ret));
return;
}

ret = i2c_driver_install(I2C_NUM_0, I2C_MODE_MASTER, 0, 0, 0);
esp_err_t ret = i2c_new_master_bus(&bus_config, &global_bus_handle);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Erro em i2c_driver_install: %s", esp_err_to_name(ret));
return;
ESP_LOGE(TAG, "Erro ao inicializar i2c_new_master_bus: %s", esp_err_to_name(ret));
} else {
ESP_LOGI(TAG, "I2C mestre inicializado com sucesso no I2C_NUM_0 usando o novo driver.");
}
}

ESP_LOGI(TAG, "I2C mestre inicializado com sucesso no I2C_NUM_0.");
i2c_master_bus_handle_t i2c_get_bus_handle(void) {
return global_bus_handle;
}
4 changes: 4 additions & 0 deletions firmware_p4/components/Drivers/i2c_init/include/i2c_init.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,8 @@


#pragma once

#include "driver/i2c_master.h"

void init_i2c(void);
i2c_master_bus_handle_t i2c_get_bus_handle(void);
3 changes: 2 additions & 1 deletion firmware_p4/components/Drivers/pn7150/include/pn7150.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
#ifndef PN7150_H
#define PN7150_H

#include "driver/i2c.h"
#include "driver/i2c_master.h"
#include "i2c_init.h"
#include "driver/gpio.h"

// Configurações de hardware
Expand Down
Loading
Loading