kopia lustrzana https://github.com/OpenRTX/OpenRTX
ttwrplus: implement PMU support
Begin implementing PMU, now successfully read and write registers, need to implement button functionality, battery voltage readout, charge detection etc. TG-553pull/193/head
rodzic
c5a63d8767
commit
8e8daa78c8
|
@ -81,9 +81,6 @@ target_include_directories(app
|
|||
subprojects/codec2
|
||||
subprojects/codec2/src
|
||||
|
||||
subprojects/XPowersLib/src
|
||||
subprojects/XPowersLib/src/REG
|
||||
|
||||
lib/minmea/include
|
||||
lib/qdec/include
|
||||
)
|
||||
|
@ -151,7 +148,5 @@ target_sources(app
|
|||
subprojects/codec2/src/codebooknewamp1.c
|
||||
subprojects/codec2/src/codebooknewamp1_energy.c
|
||||
|
||||
subprojects/XPowersLib/src/XPowersLibInterface.cpp
|
||||
|
||||
lib/minmea/minmea.c
|
||||
)
|
||||
|
|
|
@ -10,6 +10,7 @@ target_sources(app
|
|||
${OPENRTX_ROOT}/platform/mcu/ESP32S3/drivers/delays.c
|
||||
|
||||
${OPENRTX_ROOT}/platform/targets/ttwrplus/platform.c
|
||||
${OPENRTX_ROOT}/platform/targets/ttwrplus/pmu.cpp
|
||||
|
||||
${OPENRTX_ROOT}/platform/drivers/display/SH1106_ttwrplus.c
|
||||
${OPENRTX_ROOT}/platform/drivers/keyboard/keyboard_ttwrplus.c
|
||||
|
@ -18,11 +19,16 @@ target_sources(app
|
|||
${OPENRTX_ROOT}/platform/drivers/stubs/cps_io_stub.c
|
||||
${OPENRTX_ROOT}/platform/drivers/stubs/nvmem_stub.c
|
||||
${OPENRTX_ROOT}/platform/drivers/stubs/radio_stub.c
|
||||
|
||||
${OPENRTX_ROOT}/subprojects/XPowersLib/src/XPowersLibInterface.cpp
|
||||
)
|
||||
|
||||
target_include_directories(app
|
||||
PRIVATE
|
||||
${OPENRTX_ROOT}/platform/targets/ttwrplus
|
||||
|
||||
${OPENRTX_ROOT}/subprojects/XPowersLib/src
|
||||
${OPENRTX_ROOT}/subprojects/XPowersLib/src/REG
|
||||
)
|
||||
|
||||
target_compile_definitions(app PRIVATE PLATFORM_TTWRPLUS)
|
||||
|
|
|
@ -18,16 +18,19 @@
|
|||
***************************************************************************/
|
||||
|
||||
#include <interfaces/platform.h>
|
||||
#include <interfaces/delays.h>
|
||||
#include <hwconfig.h>
|
||||
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/drivers/sensor.h>
|
||||
#include "pmu.h"
|
||||
|
||||
#define BUTTON_PTT_NODE DT_NODELABEL(button_ptt)
|
||||
|
||||
static const struct gpio_dt_spec button_ptt = GPIO_DT_SPEC_GET_OR(BUTTON_PTT_NODE, gpios, {0});
|
||||
static const struct device *const qdec_dev = DEVICE_DT_GET(DT_ALIAS(qdec0));
|
||||
|
||||
|
||||
static const hwInfo_t hwInfo =
|
||||
{
|
||||
.uhf_maxFreq = 430,
|
||||
|
@ -36,7 +39,6 @@ static const hwInfo_t hwInfo =
|
|||
.name = "ttwrplus"
|
||||
};
|
||||
|
||||
|
||||
void platform_init()
|
||||
{
|
||||
// Setup GPIO for PTT and rotary encoder
|
||||
|
@ -53,6 +55,9 @@ void platform_init()
|
|||
// Rotary encoder is read using hardware pulse counter
|
||||
if(device_is_ready(qdec_dev) == false)
|
||||
printk("Qdec device is not ready\n");
|
||||
|
||||
// Initialize PMU
|
||||
pmu_init();
|
||||
}
|
||||
|
||||
void platform_terminate()
|
||||
|
|
|
@ -0,0 +1,292 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2023 by Federico Amedeo Izzo IU2NUO, *
|
||||
* Niccolò Izzo IU2KIN *
|
||||
* Silvano Seva IU2KWO *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/> *
|
||||
***************************************************************************/
|
||||
|
||||
#include <zephyr/drivers/i2c.h>
|
||||
#include <interfaces/delays.h>
|
||||
#include <hwconfig.h>
|
||||
#include "pmu.h"
|
||||
|
||||
// PMU is controlled through the XPowersLib external library
|
||||
#define XPOWERS_CHIP_AXP2101
|
||||
#include <XPowersLib.h>
|
||||
|
||||
|
||||
#if DT_NODE_HAS_STATUS(DT_ALIAS(i2c_0), okay)
|
||||
#define I2C_DEV_NODE DT_ALIAS(i2c_0)
|
||||
#else
|
||||
#error "Please set the correct I2C device"
|
||||
#endif
|
||||
|
||||
|
||||
static const struct device *const i2c_dev = DEVICE_DT_GET(I2C_DEV_NODE);
|
||||
static XPowersPMU PMU;
|
||||
|
||||
|
||||
static int pmu_registerReadByte(uint8_t devAddr, uint8_t regAddr, uint8_t *data,
|
||||
uint8_t len)
|
||||
{
|
||||
// Only single-byte reads are supported
|
||||
if (len != 1)
|
||||
return -1;
|
||||
|
||||
return i2c_reg_read_byte(i2c_dev, devAddr, regAddr, data);
|
||||
}
|
||||
|
||||
static int pmu_registerWriteByte(uint8_t devAddr, uint8_t regAddr, uint8_t *data,
|
||||
uint8_t len)
|
||||
{
|
||||
// Only single-byte writes are supported
|
||||
if (len != 1)
|
||||
return -1;
|
||||
|
||||
return i2c_reg_write_byte(i2c_dev, devAddr, regAddr, *data);
|
||||
}
|
||||
|
||||
|
||||
void pmu_init()
|
||||
{
|
||||
// Configure I2C connection with PMU
|
||||
if (device_is_ready(i2c_dev) == false)
|
||||
{
|
||||
printk("I2C device is not ready\n");
|
||||
}
|
||||
|
||||
const uint32_t i2c_cfg = I2C_SPEED_SET(I2C_SPEED_FAST) | I2C_MODE_CONTROLLER;
|
||||
if (i2c_configure(i2c_dev, i2c_cfg) != 0)
|
||||
{
|
||||
printk("I2C config failed\n");
|
||||
}
|
||||
|
||||
bool result = PMU.begin(AXP2101_SLAVE_ADDRESS, pmu_registerReadByte,
|
||||
pmu_registerWriteByte);
|
||||
if (result == false)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
printk("PMU is not online...");
|
||||
delayMs(500);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the minimum common working voltage of the PMU VBUS input,
|
||||
// below this value will turn off the PMU
|
||||
PMU.setVbusVoltageLimit(XPOWERS_AXP2101_VBUS_VOL_LIM_3V88);
|
||||
|
||||
// Set the maximum current of the PMU VBUS input,
|
||||
// higher than this value will turn off the PMU
|
||||
PMU.setVbusCurrentLimit(XPOWERS_AXP2101_VBUS_CUR_LIM_2000MA);
|
||||
|
||||
// Get the VSYS shutdown voltage
|
||||
uint16_t vol = PMU.getSysPowerDownVoltage();
|
||||
printk("-> getSysPowerDownVoltage:%u\n", vol);
|
||||
|
||||
// Set VSY off voltage as 2600mV , Adjustment range 2600mV ~ 3300mV
|
||||
PMU.setSysPowerDownVoltage(2600);
|
||||
|
||||
|
||||
//! DC1 ESP32S3 Core VDD , Don't change
|
||||
// PMU.setDC1Voltage(3300);
|
||||
|
||||
//! DC3 Radio & Pixels VDD , Don't change
|
||||
PMU.setDC3Voltage(3400);
|
||||
|
||||
//! ALDO2 MICRO TF Card VDD, Don't change
|
||||
PMU.setALDO2Voltage(3300);
|
||||
|
||||
//! ALDO4 GNSS VDD, Don't change
|
||||
PMU.setALDO4Voltage(3300);
|
||||
|
||||
//! BLDO1 MIC VDD, Don't change
|
||||
PMU.setBLDO1Voltage(3300);
|
||||
|
||||
// DC5 IMAX=2A
|
||||
// 1200mV
|
||||
// 1400~3700mV,100mV/step,24steps
|
||||
PMU.setDC5Voltage(3300);
|
||||
|
||||
//ALDO1 IMAX=300mA
|
||||
//500~3500mV, 100mV/step,31steps
|
||||
PMU.setALDO1Voltage(3300);
|
||||
|
||||
//ALDO3 IMAX=300mA
|
||||
//500~3500mV, 100mV/step,31steps
|
||||
PMU.setALDO3Voltage(3300);
|
||||
|
||||
//BLDO2 IMAX=300mA
|
||||
//500~3500mV, 100mV/step,31steps
|
||||
PMU.setBLDO2Voltage(3300);
|
||||
|
||||
// Turn on the power that needs to be used
|
||||
//! DC1 ESP32S3 Core VDD , Don't change
|
||||
// PMU.enableDC3();
|
||||
|
||||
//! External pin power supply
|
||||
PMU.enableDC5();
|
||||
PMU.enableALDO1();
|
||||
PMU.enableALDO3();
|
||||
PMU.enableBLDO2();
|
||||
|
||||
//! ALDO2 MICRO TF Card VDD
|
||||
PMU.enableALDO2();
|
||||
|
||||
//! ALDO4 GNSS VDD
|
||||
PMU.enableALDO4();
|
||||
|
||||
//! BLDO1 MIC VDD
|
||||
PMU.enableBLDO1();
|
||||
|
||||
//! DC3 Radio & Pixels VDD
|
||||
PMU.enableDC3();
|
||||
|
||||
// power off when not in use
|
||||
PMU.disableDC2();
|
||||
PMU.disableDC4();
|
||||
PMU.disableCPUSLDO();
|
||||
PMU.disableDLDO1();
|
||||
PMU.disableDLDO2();
|
||||
|
||||
|
||||
printk("DCDC=======================================================================\n");
|
||||
printk("DC1 : %s Voltage:%u mV \n", PMU.isEnableDC1() ? "+" : "-", PMU.getDC1Voltage());
|
||||
printk("DC2 : %s Voltage:%u mV \n", PMU.isEnableDC2() ? "+" : "-", PMU.getDC2Voltage());
|
||||
printk("DC3 : %s Voltage:%u mV \n", PMU.isEnableDC3() ? "+" : "-", PMU.getDC3Voltage());
|
||||
printk("DC4 : %s Voltage:%u mV \n", PMU.isEnableDC4() ? "+" : "-", PMU.getDC4Voltage());
|
||||
printk("DC5 : %s Voltage:%u mV \n", PMU.isEnableDC5() ? "+" : "-", PMU.getDC5Voltage());
|
||||
printk("ALDO=======================================================================\n");
|
||||
printk("ALDO1: %s Voltage:%u mV\n", PMU.isEnableALDO1() ? "+" : "-", PMU.getALDO1Voltage());
|
||||
printk("ALDO2: %s Voltage:%u mV\n", PMU.isEnableALDO2() ? "+" : "-", PMU.getALDO2Voltage());
|
||||
printk("ALDO3: %s Voltage:%u mV\n", PMU.isEnableALDO3() ? "+" : "-", PMU.getALDO3Voltage());
|
||||
printk("ALDO4: %s Voltage:%u mV\n", PMU.isEnableALDO4() ? "+" : "-", PMU.getALDO4Voltage());
|
||||
printk("BLDO=======================================================================\n");
|
||||
printk("BLDO1: %s Voltage:%u mV\n", PMU.isEnableBLDO1() ? "+" : "-", PMU.getBLDO1Voltage());
|
||||
printk("BLDO2: %s Voltage:%u mV\n", PMU.isEnableBLDO2() ? "+" : "-", PMU.getBLDO2Voltage());
|
||||
printk("===========================================================================\n");
|
||||
|
||||
// Set the time of pressing the button to turn off
|
||||
PMU.setPowerKeyPressOffTime(XPOWERS_POWEROFF_4S);
|
||||
uint8_t opt = PMU.getPowerKeyPressOffTime();
|
||||
printk("PowerKeyPressOffTime:");
|
||||
switch (opt)
|
||||
{
|
||||
case XPOWERS_POWEROFF_4S: printk("4 Second");
|
||||
break;
|
||||
case XPOWERS_POWEROFF_6S: printk("6 Second");
|
||||
break;
|
||||
case XPOWERS_POWEROFF_8S: printk("8 Second");
|
||||
break;
|
||||
case XPOWERS_POWEROFF_10S: printk("10 Second");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
printk("\n");
|
||||
|
||||
// Set the button power-on press time
|
||||
PMU.setPowerKeyPressOnTime(XPOWERS_POWERON_128MS);
|
||||
opt = PMU.getPowerKeyPressOnTime();
|
||||
printk("PowerKeyPressOnTime:");
|
||||
switch (opt)
|
||||
{
|
||||
case XPOWERS_POWERON_128MS: printk("128 Ms");
|
||||
break;
|
||||
case XPOWERS_POWERON_512MS: printk("512 Ms");
|
||||
break;
|
||||
case XPOWERS_POWERON_1S: printk("1 Second");
|
||||
break;
|
||||
case XPOWERS_POWERON_2S: printk("2 Second");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
printk("\n");
|
||||
|
||||
printk("===========================================================================\n");
|
||||
// It is necessary to disable the detection function of the TS pin on the board
|
||||
// without the battery temperature detection function, otherwise it will cause abnormal charging
|
||||
PMU.disableTSPinMeasure();
|
||||
|
||||
// Enable internal ADC detection
|
||||
PMU.enableBattDetection();
|
||||
PMU.enableVbusVoltageMeasure();
|
||||
PMU.enableBattVoltageMeasure();
|
||||
PMU.enableSystemVoltageMeasure();
|
||||
|
||||
/*
|
||||
The default setting is CHGLED is automatically controlled by the PMU.
|
||||
- XPOWERS_CHG_LED_OFF,
|
||||
- XPOWERS_CHG_LED_BLINK_1HZ,
|
||||
- XPOWERS_CHG_LED_BLINK_4HZ,
|
||||
- XPOWERS_CHG_LED_ON,
|
||||
- XPOWERS_CHG_LED_CTRL_CHG,
|
||||
* */
|
||||
PMU.setChargingLedMode(XPOWERS_CHG_LED_BLINK_1HZ);
|
||||
|
||||
// TODO: Implement IRQ
|
||||
// pinMode(PMU_IRQ, INPUT_PULLUP);
|
||||
// attachInterrupt(PMU_IRQ, setFlag, FALLING);
|
||||
|
||||
// Disable all interrupts
|
||||
PMU.disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
|
||||
// Clear all interrupt flags
|
||||
PMU.clearIrqStatus();
|
||||
// Enable the required interrupt function
|
||||
PMU.enableIRQ(
|
||||
XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_BAT_REMOVE_IRQ | //BATTERY
|
||||
XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_VBUS_REMOVE_IRQ | //VBUS
|
||||
XPOWERS_AXP2101_PKEY_SHORT_IRQ | XPOWERS_AXP2101_PKEY_LONG_IRQ | //POWER KEY
|
||||
XPOWERS_AXP2101_BAT_CHG_DONE_IRQ | XPOWERS_AXP2101_BAT_CHG_START_IRQ //CHARGE
|
||||
);
|
||||
|
||||
// Set the precharge charging current
|
||||
PMU.setPrechargeCurr(XPOWERS_AXP2101_PRECHARGE_150MA);
|
||||
|
||||
// Set constant current charge current limit
|
||||
//! Using inferior USB cables and adapters will not reach the maximum charging current.
|
||||
//! Please pay attention to add a suitable heat sink above the PMU when setting the charging current to 1A
|
||||
PMU.setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_1000MA);
|
||||
|
||||
// Set stop charging termination current
|
||||
PMU.setChargerTerminationCurr(XPOWERS_AXP2101_CHG_ITERM_150MA);
|
||||
|
||||
// Set charge cut-off voltage
|
||||
PMU.setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V2);
|
||||
|
||||
// Disable the PMU long press shutdown function
|
||||
PMU.disableLongPressShutdown();
|
||||
|
||||
|
||||
// Get charging target current
|
||||
static const uint16_t currTable[] =
|
||||
{
|
||||
0, 0, 0, 0, 100, 125, 150, 175, 200, 300, 400, 500, 600, 700, 800, 900, 1000
|
||||
};
|
||||
|
||||
uint8_t val = PMU.getChargerConstantCurr();
|
||||
printk("Val = %d\n", val);
|
||||
printk("Setting Charge Target Current : %d\n", currTable[val]);
|
||||
|
||||
// Get charging target voltage
|
||||
static const uint16_t tableVoltage[] =
|
||||
{
|
||||
0, 4000, 4100, 4200, 4350, 4400, 255
|
||||
};
|
||||
|
||||
val = PMU.getChargeTargetVoltage();
|
||||
printk("Setting Charge Target Voltage : %d\n", tableVoltage[val]);
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2023 by Federico Amedeo Izzo IU2NUO, *
|
||||
* Niccolò Izzo IU2KIN *
|
||||
* Silvano Seva IU2KWO *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/> *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef PMU_H
|
||||
#define PMU_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void pmu_init();
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // PMU_H
|
Plik diff jest za duży
Load Diff
Ładowanie…
Reference in New Issue