mirror of
https://github.com/Lurkars/esp-ena.git
synced 2024-11-01 11:04:39 +01:00
484 lines
11 KiB
C
484 lines
11 KiB
C
|
// Copyright 2020 Lukas Haubaum
|
||
|
//
|
||
|
// Licensed under the GNU Affero General Public License, Version 3;
|
||
|
// you may not use this file except in compliance with the License.
|
||
|
// You may obtain a copy of the License at
|
||
|
|
||
|
// https://www.gnu.org/licenses/agpl-3.0.html
|
||
|
//
|
||
|
// Unless required by applicable law or agreed to in writing, software
|
||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
// See the License for the specific language governing permissions and
|
||
|
// limitations under the License.
|
||
|
#include <stdio.h>
|
||
|
#include <time.h>
|
||
|
|
||
|
#include "driver/i2c.h"
|
||
|
#include "esp_sleep.h"
|
||
|
#include "esp_log.h"
|
||
|
|
||
|
#include "i2c-main.h"
|
||
|
|
||
|
#include "axp192.h"
|
||
|
|
||
|
void axp192_write_byte(uint8_t addr, uint8_t data)
|
||
|
{
|
||
|
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||
|
|
||
|
i2c_master_start(cmd);
|
||
|
// Begin the I2C comm with AXP192_ADDRESS's address (SLA+Write)
|
||
|
i2c_master_write_byte(cmd, (AXP192_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
||
|
|
||
|
i2c_master_write_byte(cmd, addr, true);
|
||
|
i2c_master_write_byte(cmd, data, true);
|
||
|
|
||
|
i2c_master_stop(cmd);
|
||
|
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS));
|
||
|
i2c_cmd_link_delete(cmd);
|
||
|
}
|
||
|
|
||
|
void axp192_read_buff(uint8_t addr, uint8_t size, uint8_t *buff)
|
||
|
{
|
||
|
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||
|
|
||
|
// Send register address
|
||
|
i2c_master_start(cmd);
|
||
|
i2c_master_write_byte(cmd, (AXP192_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
||
|
i2c_master_write_byte(cmd, addr, true);
|
||
|
|
||
|
// Receive data
|
||
|
i2c_master_start(cmd);
|
||
|
i2c_master_write_byte(cmd, (AXP192_ADDRESS << 1) | I2C_MASTER_READ, true);
|
||
|
i2c_master_read(cmd, buff, size, I2C_MASTER_LAST_NACK);
|
||
|
|
||
|
i2c_master_stop(cmd);
|
||
|
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS));
|
||
|
i2c_cmd_link_delete(cmd);
|
||
|
}
|
||
|
|
||
|
uint8_t axp192_read_8bit(uint8_t addr)
|
||
|
{
|
||
|
uint8_t data;
|
||
|
axp192_read_buff(addr, 1, &data);
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
uint16_t axp192_read_12bit(uint8_t addr)
|
||
|
{
|
||
|
uint16_t data = 0;
|
||
|
uint8_t buf[2];
|
||
|
axp192_read_buff(addr, 2, buf);
|
||
|
data = ((buf[0] << 4) + buf[1]); //
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
uint16_t axp192_read_13bit(uint8_t addr)
|
||
|
{
|
||
|
uint16_t data = 0;
|
||
|
uint8_t buf[2];
|
||
|
axp192_read_buff(addr, 2, buf);
|
||
|
data = ((buf[0] << 5) + buf[1]); //
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
uint16_t axp192_read_16bit(uint8_t addr)
|
||
|
{
|
||
|
uint16_t data = 0;
|
||
|
uint8_t buf[2];
|
||
|
axp192_read_buff(addr, 2, buf);
|
||
|
data = ((buf[0] << 8) + buf[1]);
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
uint32_t axp192_read_24bit(uint8_t addr)
|
||
|
{
|
||
|
uint32_t data = 0;
|
||
|
uint8_t buf[3];
|
||
|
axp192_read_buff(addr, 3, buf);
|
||
|
data = ((buf[0] << 16) + (buf[1] << 8) + buf[2]);
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
uint32_t axp192_read_32bit(uint8_t addr)
|
||
|
{
|
||
|
uint32_t data = 0;
|
||
|
uint8_t buf[4];
|
||
|
axp192_read_buff(addr, 4, buf);
|
||
|
data = ((buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3]);
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
void axp192_screen_breath(uint8_t brightness)
|
||
|
{
|
||
|
if (brightness > 12)
|
||
|
{
|
||
|
brightness = 12;
|
||
|
}
|
||
|
uint8_t buf = axp192_read_8bit(0x28);
|
||
|
axp192_write_byte(0x28, ((buf & 0x0f) | (brightness << 4)));
|
||
|
}
|
||
|
|
||
|
void axp192_start(void)
|
||
|
{
|
||
|
if (!i2c_is_initialized())
|
||
|
{
|
||
|
i2c_main_init();
|
||
|
}
|
||
|
|
||
|
// Set LDO2 & LDO3(ST7789_LED & TFT) 3.0V
|
||
|
axp192_write_byte(0x28, 0xcc);
|
||
|
|
||
|
// Set ADC sample rate to 200hz
|
||
|
axp192_write_byte(0x84, 0xF2);
|
||
|
|
||
|
// Set ADC to All Enable
|
||
|
axp192_write_byte(0x82, 0xff);
|
||
|
|
||
|
// Bat charge voltage to 4.2, Current 100MA
|
||
|
axp192_write_byte(0x33, 0xc0);
|
||
|
|
||
|
// Enable Bat,ACIN,VBUS,APS adc
|
||
|
axp192_write_byte(0x82, 0xff);
|
||
|
|
||
|
// Enable Ext, LDO2, LDO3, DCDC1
|
||
|
axp192_write_byte(0x12, axp192_read_8bit(0x12) | 0x4D);
|
||
|
|
||
|
// 128ms power on, 4s power off
|
||
|
axp192_write_byte(0x36, 0x0C);
|
||
|
|
||
|
// Set RTC voltage to 3.3V
|
||
|
axp192_write_byte(0x91, 0xF0);
|
||
|
|
||
|
// Set GPIO0 to LDO
|
||
|
axp192_write_byte(0x90, 0x02);
|
||
|
|
||
|
// Disable vbus hold limit
|
||
|
axp192_write_byte(0x30, 0x80);
|
||
|
|
||
|
// Set temperature protection
|
||
|
axp192_write_byte(0x39, 0xfc);
|
||
|
|
||
|
// Enable RTC BAT charge
|
||
|
axp192_write_byte(0x35, 0xa2);
|
||
|
|
||
|
// Enable bat detection
|
||
|
axp192_write_byte(0x32, 0x46);
|
||
|
}
|
||
|
|
||
|
bool axp192_get_bat_state()
|
||
|
{
|
||
|
if (axp192_read_8bit(0x01) | 0x20)
|
||
|
return true;
|
||
|
else
|
||
|
return false;
|
||
|
}
|
||
|
//---------coulombcounter_from_here---------
|
||
|
//enable: void EnableCoulombcounter(void);
|
||
|
//disable: void DisableCOulombcounter(void);
|
||
|
//stop: void StopCoulombcounter(void);
|
||
|
//clear: void ClearCoulombcounter(void);
|
||
|
//get charge data: uint32_t GetCoulombchargedata(void);
|
||
|
//get discharge data: uint32_t GetCoulombdischargedata(void);
|
||
|
//get coulomb val affter calculation: float GetCoulombdata(void);
|
||
|
//------------------------------------------
|
||
|
void axp192_enable_coulombcounter(void)
|
||
|
{
|
||
|
axp192_write_byte(0xB8, 0x80);
|
||
|
}
|
||
|
|
||
|
void axp192_disable_coulombcounter(void)
|
||
|
{
|
||
|
axp192_write_byte(0xB8, 0x00);
|
||
|
}
|
||
|
|
||
|
void axp192_stop_coulombcounter(void)
|
||
|
{
|
||
|
axp192_write_byte(0xB8, 0xC0);
|
||
|
}
|
||
|
|
||
|
void axp192_clear_coulombcounter(void)
|
||
|
{
|
||
|
axp192_write_byte(0xB8, 0xA0);
|
||
|
}
|
||
|
|
||
|
uint32_t axp192_get_coulombcharge_data(void)
|
||
|
{
|
||
|
return axp192_read_32bit(0xB0);
|
||
|
}
|
||
|
|
||
|
uint32_t axp192_get_coulombdischarge_data(void)
|
||
|
{
|
||
|
return axp192_read_32bit(0xB4);
|
||
|
}
|
||
|
|
||
|
float axp192_get_coulomb_data(void)
|
||
|
{
|
||
|
|
||
|
uint32_t coin = 0;
|
||
|
uint32_t coout = 0;
|
||
|
|
||
|
coin = axp192_get_coulombcharge_data();
|
||
|
coout = axp192_get_coulombdischarge_data();
|
||
|
|
||
|
//c = 65536 * current_LSB * (coin - coout) / 3600 / ADC rate
|
||
|
//Adc rate can be read from 84H ,change this variable if you change the ADC reate
|
||
|
float ccc = 65536 * 0.5 * (coin - coout) / 3600.0 / 25.0;
|
||
|
return ccc;
|
||
|
}
|
||
|
//----------coulomb_end_at_here----------
|
||
|
|
||
|
uint16_t axp192_get_Vbatdata(void)
|
||
|
{
|
||
|
|
||
|
uint16_t vbat = 0;
|
||
|
uint8_t buf[2];
|
||
|
axp192_read_buff(0x78, 2, buf);
|
||
|
vbat = ((buf[0] << 4) + buf[1]); // V
|
||
|
return vbat;
|
||
|
}
|
||
|
|
||
|
uint16_t axp192_get_Vindata(void)
|
||
|
{
|
||
|
uint16_t vin = 0;
|
||
|
uint8_t buf[2];
|
||
|
axp192_read_buff(0x56, 2, buf);
|
||
|
vin = ((buf[0] << 4) + buf[1]); // V
|
||
|
return vin;
|
||
|
}
|
||
|
|
||
|
uint16_t axp192_get_Iindata(void)
|
||
|
{
|
||
|
uint16_t iin = 0;
|
||
|
uint8_t buf[2];
|
||
|
axp192_read_buff(0x58, 2, buf);
|
||
|
iin = ((buf[0] << 4) + buf[1]);
|
||
|
return iin;
|
||
|
}
|
||
|
|
||
|
uint16_t axp192_get_Vusbindata(void)
|
||
|
{
|
||
|
uint16_t vin = 0;
|
||
|
uint8_t buf[2];
|
||
|
axp192_read_buff(0x5a, 2, buf);
|
||
|
vin = ((buf[0] << 4) + buf[1]); // V
|
||
|
return vin;
|
||
|
}
|
||
|
|
||
|
uint16_t axp192_get_Iusbindata(void)
|
||
|
{
|
||
|
uint16_t iin = 0;
|
||
|
uint8_t buf[2];
|
||
|
axp192_read_buff(0x5C, 2, buf);
|
||
|
iin = ((buf[0] << 4) + buf[1]);
|
||
|
return iin;
|
||
|
}
|
||
|
|
||
|
uint16_t axp192_get_Ichargedata(void)
|
||
|
{
|
||
|
|
||
|
uint16_t icharge = 0;
|
||
|
uint8_t buf[2];
|
||
|
axp192_read_buff(0x7A, 2, buf);
|
||
|
icharge = (buf[0] << 5) + buf[1];
|
||
|
return icharge;
|
||
|
}
|
||
|
|
||
|
uint16_t axp192_get_Idischargedata(void)
|
||
|
{
|
||
|
uint16_t idischarge = 0;
|
||
|
uint8_t buf[2];
|
||
|
axp192_read_buff(0x7C, 2, buf);
|
||
|
idischarge = (buf[0] << 5) + buf[1];
|
||
|
return idischarge;
|
||
|
}
|
||
|
|
||
|
uint16_t axp192_get_Tempdata(void)
|
||
|
{
|
||
|
uint16_t temp = 0;
|
||
|
uint8_t buf[2];
|
||
|
axp192_read_buff(0x5e, 2, buf);
|
||
|
temp = ((buf[0] << 4) + buf[1]);
|
||
|
return temp;
|
||
|
}
|
||
|
|
||
|
uint32_t axp192_get_Powerbatdata(void)
|
||
|
{
|
||
|
uint32_t power = 0;
|
||
|
uint8_t buf[3];
|
||
|
axp192_read_buff(0x70, 2, buf);
|
||
|
power = (buf[0] << 16) + (buf[1] << 8) + buf[2];
|
||
|
return power;
|
||
|
}
|
||
|
|
||
|
uint16_t axp192_get_Vapsdata(void)
|
||
|
{
|
||
|
uint16_t vaps = 0;
|
||
|
uint8_t buf[2];
|
||
|
axp192_read_buff(0x7e, 2, buf);
|
||
|
vaps = ((buf[0] << 4) + buf[1]);
|
||
|
return vaps;
|
||
|
}
|
||
|
|
||
|
void axp192_set_sleep(void)
|
||
|
{
|
||
|
uint8_t buf = axp192_read_8bit(0x31);
|
||
|
buf = (1 << 3) | buf;
|
||
|
axp192_write_byte(0x31, buf);
|
||
|
axp192_write_byte(0x90, 0x00);
|
||
|
axp192_write_byte(0x12, 0x09);
|
||
|
axp192_write_byte(0x12, 0x00);
|
||
|
}
|
||
|
|
||
|
uint8_t axp192_get_warning_leve(void)
|
||
|
{
|
||
|
uint8_t buf = axp192_read_8bit(0x47);
|
||
|
return (buf & 0x01);
|
||
|
}
|
||
|
|
||
|
// -- sleep
|
||
|
void axp192_deep_sleep(uint64_t time_in_us)
|
||
|
{
|
||
|
axp192_set_sleep();
|
||
|
|
||
|
if (time_in_us > 0)
|
||
|
{
|
||
|
esp_sleep_enable_timer_wakeup(time_in_us);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER);
|
||
|
}
|
||
|
(time_in_us == 0) ? esp_deep_sleep_start() : esp_deep_sleep(time_in_us);
|
||
|
}
|
||
|
|
||
|
void axp192_light_sleep(uint64_t time_in_us)
|
||
|
{
|
||
|
axp192_set_sleep();
|
||
|
|
||
|
if (time_in_us > 0)
|
||
|
{
|
||
|
esp_sleep_enable_timer_wakeup(time_in_us);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER);
|
||
|
}
|
||
|
esp_light_sleep_start();
|
||
|
}
|
||
|
|
||
|
// 0 not press, 0x01 long press, 0x02 press
|
||
|
uint8_t axp192_get_btn_press()
|
||
|
{
|
||
|
uint8_t state = axp192_read_8bit(0x46);
|
||
|
if (state)
|
||
|
{
|
||
|
axp192_write_byte(0x46, 0x03);
|
||
|
}
|
||
|
return state;
|
||
|
}
|
||
|
|
||
|
uint8_t axp192_get_warning_level(void)
|
||
|
{
|
||
|
return axp192_read_8bit(0x47) & 0x01;
|
||
|
}
|
||
|
|
||
|
float axp192_get_bat_voltage()
|
||
|
{
|
||
|
float ADCLSB = 1.1 / 1000.0;
|
||
|
uint16_t Redata = axp192_read_12bit(0x78);
|
||
|
return Redata * ADCLSB;
|
||
|
}
|
||
|
|
||
|
float axp192_get_bat_current()
|
||
|
{
|
||
|
float ADCLSB = 0.5;
|
||
|
uint16_t CurrentIn = axp192_read_13bit(0x7A);
|
||
|
uint16_t CurrentOut = axp192_read_13bit(0x7C);
|
||
|
return (CurrentIn - CurrentOut) * ADCLSB;
|
||
|
}
|
||
|
|
||
|
float axp192_get_vin_voltage()
|
||
|
{
|
||
|
float ADCLSB = 1.7 / 1000.0;
|
||
|
uint16_t Redata = axp192_read_12bit(0x56);
|
||
|
return Redata * ADCLSB;
|
||
|
}
|
||
|
|
||
|
float axp192_get_vin_current()
|
||
|
{
|
||
|
float ADCLSB = 0.625;
|
||
|
uint16_t Redata = axp192_read_12bit(0x58);
|
||
|
return Redata * ADCLSB;
|
||
|
}
|
||
|
|
||
|
float axp192_get_vbus_voltage()
|
||
|
{
|
||
|
float ADCLSB = 1.7 / 1000.0;
|
||
|
uint16_t Redata = axp192_read_12bit(0x5A);
|
||
|
return Redata * ADCLSB;
|
||
|
}
|
||
|
|
||
|
float axp192_get_vbus_current()
|
||
|
{
|
||
|
float ADCLSB = 0.375;
|
||
|
uint16_t Redata = axp192_read_12bit(0x5C);
|
||
|
return Redata * ADCLSB;
|
||
|
}
|
||
|
|
||
|
float axp192_get_temp()
|
||
|
{
|
||
|
float ADCLSB = 0.1;
|
||
|
const float OFFSET_DEG_C = -144.7;
|
||
|
uint16_t Redata = axp192_read_12bit(0x5E);
|
||
|
return OFFSET_DEG_C + Redata * ADCLSB;
|
||
|
}
|
||
|
|
||
|
float axp192_get_bat_power()
|
||
|
{
|
||
|
float VoltageLSB = 1.1;
|
||
|
float CurrentLCS = 0.5;
|
||
|
uint32_t Redata = axp192_read_24bit(0x70);
|
||
|
return VoltageLSB * CurrentLCS * Redata / 1000.0;
|
||
|
}
|
||
|
|
||
|
float axp192_get_bat_charge_current()
|
||
|
{
|
||
|
float ADCLSB = 0.5;
|
||
|
uint16_t Redata = axp192_read_12bit(0x7A);
|
||
|
return Redata * ADCLSB;
|
||
|
}
|
||
|
float axp192_get_aps_voltage()
|
||
|
{
|
||
|
float ADCLSB = 1.4 / 1000.0;
|
||
|
uint16_t Redata = axp192_read_12bit(0x7E);
|
||
|
return Redata * ADCLSB;
|
||
|
}
|
||
|
|
||
|
float axp192_get_bat_coulomb_input()
|
||
|
{
|
||
|
uint32_t Redata = axp192_read_32bit(0xB0);
|
||
|
return Redata * 65536 * 0.5 / 3600 / 25.0;
|
||
|
}
|
||
|
|
||
|
float axp192_get_bat_coulomb_out()
|
||
|
{
|
||
|
uint32_t Redata = axp192_read_32bit(0xB4);
|
||
|
return Redata * 65536 * 0.5 / 3600 / 25.0;
|
||
|
}
|
||
|
|
||
|
void axp192_set_coulomb_clear()
|
||
|
{
|
||
|
axp192_write_byte(0xB8, 0x20);
|
||
|
}
|
||
|
|
||
|
void axp192_set_ldo2(bool state)
|
||
|
{
|
||
|
uint8_t buf = axp192_read_8bit(0x12);
|
||
|
if (state == true)
|
||
|
buf = (1 << 2) | buf;
|
||
|
else
|
||
|
buf = ~(1 << 2) & buf;
|
||
|
axp192_write_byte(0x12, buf);
|
||
|
}
|