This commit is contained in:
lmx
2025-10-29 13:10:02 +08:00
commit 49a07fa419
2284 changed files with 642060 additions and 0 deletions

View File

@ -0,0 +1,28 @@
#include "asm/power_interface.h"
#include "app_config.h"
#include "includes.h"
const char BTOSC_FASTBOOT_EN = 0;
#if (TCFG_LOWPOWER_LOWPOWER_SEL == SLEEP_EN)
static enum LOW_POWER_LEVEL power_app_level(void)
{
return LOW_POWER_MODE_SLEEP;
}
static u8 power_app_idle(void)
{
return 1;
}
REGISTER_LP_TARGET(power_app_lp_target) = {
.name = "power_app",
.level = power_app_level,
.is_idle = power_app_idle,
};
#endif

View File

@ -0,0 +1,69 @@
/**@file power_check.c
* @brief 低功耗检查点
* @details HW API
* @author JL
* @date 2021-11-30
* @version V1.0
* @copyright Copyright:(c)JIELI 2011-2020 @ , All Rights Reserved.
*/
#include "asm/power_interface.h"
#include "app_config.h"
#include "includes.h"
#include "asm/clock_hw.h"
#pragma bss_seg(".volatile_ram_code")
#pragma data_seg(".volatile_ram_code")
#pragma code_seg(".volatile_ram_code")
#pragma const_seg(".volatile_ram_code")
#pragma str_literal_override(".volatile_ram_code")
void pmut_put_u8hex(u8 dat);
void pmu_put_u16hex(u16 dat);
void pmu_put_u32hex(u32 dat);
void pmu_put_u64hex(u64 dat);
void pmu_put_buf(const u8 *buf, int len);
AT_VOLATILE_RAM_CODE_POWER
u8 sleep_safety_check(void)
{
#if 0
u32 get_rch_freq();
JL_PORTA->DIR &= ~BIT(5);
JL_OMAP->PA5_OUT = FO_UART0_TX;
MAIN_CLOCK_SEL(MAIN_CLOCK_IN_RC);
HSB_CLK_DIV(0);
LSB_CLK_DIV(0);
UART_CLOCK_IN(UART_CLOCK_IN_LSB);
JL_UART0->BAUD = (get_rch_freq() * 1000 / 115200) / 4 - 1;
void check_gpio_safety();
check_gpio_safety();
void wdt_close();
wdt_close();
while (1);
#endif
return 0;
}
AT_VOLATILE_RAM_CODE_POWER
u8 soff_safety_check(void)
{
#if 0
u32 get_rch_freq();
JL_PORTA->DIR &= ~BIT(5);
JL_OMAP->PA5_OUT = FO_UART0_TX;
MAIN_CLOCK_SEL(MAIN_CLOCK_IN_RC);
HSB_CLK_DIV(0);
LSB_CLK_DIV(0);
UART_CLOCK_IN(UART_CLOCK_IN_LSB);
JL_UART0->BAUD = (get_rch_freq() * 1000 / 115200) / 4 - 1;
void check_gpio_safety();
check_gpio_safety();
#endif
return 0;
}

197
cpu/br28/power/power_port.c Normal file
View File

@ -0,0 +1,197 @@
#include "asm/power_interface.h"
#include "app_config.h"
#include "includes.h"
static u8 gpiousb = 0x3;
static u32 usb_io_con = 0;
/* cpu公共流程
* 请勿添加板级相关的流程,例如宏定义
* 可以重写改流程
* 所有io保持原状除usb io
*/
void sleep_gpio_protect(u32 gpio)
{
if (gpio == IO_PORT_DP) {
gpiousb &= ~BIT(0);
} else if (gpio == IO_PORT_DM) {
gpiousb &= ~BIT(1);
}
}
void sleep_enter_callback_common(void *priv)
{
usb_io_con = JL_USB_IO->CON0;
if (gpiousb) {
usb_iomode(1);
if (gpiousb & BIT(0)) {
gpio_set_pull_up(IO_PORT_DP, 0);
gpio_set_pull_down(IO_PORT_DP, 0);
gpio_set_direction(IO_PORT_DP, 1);
gpio_set_die(IO_PORT_DP, 0);
gpio_set_dieh(IO_PORT_DP, 0);
}
if (gpiousb & BIT(1)) {
gpio_set_pull_up(IO_PORT_DM, 0);
gpio_set_pull_down(IO_PORT_DM, 0);
gpio_set_direction(IO_PORT_DM, 1);
gpio_set_die(IO_PORT_DM, 0);
gpio_set_dieh(IO_PORT_DM, 0);
}
}
}
void sleep_exit_callback_common(void *priv)
{
JL_USB_IO->CON0 = usb_io_con;
gpiousb = 0x3;
}
static struct gpio_value soff_gpio_config = {
.gpioa = 0xffff,
.gpiob = 0xffff,
.gpioc = 0xffff,
.gpiod = 0xffff,
.gpioe = 0xffff,
.gpiog = 0xffff,
.gpiop = 0x1,//
.gpiousb = 0x3,
};
void soff_gpio_protect(u32 gpio)
{
if ((gpio >= 0) && (gpio < IO_MAX_NUM)) {
port_protect((u16 *)&soff_gpio_config, gpio);
} else if (gpio == IO_PORT_DP) {
soff_gpio_config.gpiousb &= ~BIT(0);
} else if (gpio == IO_PORT_DM) {
soff_gpio_config.gpiousb &= ~BIT(1);
}
}
/* cpu公共流程
* 请勿添加板级相关的流程,例如宏定义
* 可以重写改流程
* 释放除内置flash外的所有io
*/
//maskrom 使用到的io
static void mask_io_cfg()
{
struct boot_soft_flag_t boot_soft_flag = {0};
boot_soft_flag.flag0.boot_ctrl.wdt_dis = 0;
boot_soft_flag.flag0.boot_ctrl.poweroff = 0;
boot_soft_flag.flag0.boot_ctrl.is_port_b = JL_IOMAP->CON0 & BIT(16) ? 1 : 0;
boot_soft_flag.flag0.boot_ctrl.lvd_en = (GET_VLVD_EN() ? 1 : 0);
boot_soft_flag.flag1.misc.usbdm = SOFTFLAG_HIGH_RESISTANCE;
boot_soft_flag.flag1.misc.usbdp = SOFTFLAG_HIGH_RESISTANCE;
boot_soft_flag.flag1.misc.uart_key_port = 0;
boot_soft_flag.flag1.misc.ldoin = SOFTFLAG_HIGH_RESISTANCE;
boot_soft_flag.flag2.pg2_pg3.pg2 = SOFTFLAG_HIGH_RESISTANCE;
boot_soft_flag.flag2.pg2_pg3.pg3 = SOFTFLAG_HIGH_RESISTANCE;
boot_soft_flag.flag3.pg4_res.pg4 = SOFTFLAG_HIGH_RESISTANCE;
boot_soft_flag.flag4.fast_boot_ctrl.fast_boot = 0;
boot_soft_flag.flag4.fast_boot_ctrl.flash_stable_delay_sel = 0;
mask_softflag_config(&boot_soft_flag);
}
void board_set_soft_poweroff_common(void *priv)
{
//flash电源
if (get_sfc_port() == 0) {
soff_gpio_protect(SPI0_PWR_A);
soff_gpio_protect(SPI0_CS_A);
soff_gpio_protect(SPI0_CLK_A);
soff_gpio_protect(SPI0_DO_D0_A);
soff_gpio_protect(SPI0_DI_D1_A);
if (get_sfc_bit_mode() == 4) {
soff_gpio_protect(SPI0_WP_D2_A);
soff_gpio_protect(SPI0_HOLD_D3_A);
}
} else {
soff_gpio_protect(SPI0_PWR_B);
soff_gpio_protect(SPI0_CS_B);
soff_gpio_protect(SPI0_CLK_B);
soff_gpio_protect(SPI0_DO_D0_B);
soff_gpio_protect(SPI0_DI_D1_B);
if (get_sfc_bit_mode() == 4) {
soff_gpio_protect(SPI0_WP_D2_B);
soff_gpio_protect(SPI0_HOLD_D3_B);
}
}
mask_io_cfg();
gpio_dir(GPIOA, 0, 16, soff_gpio_config.gpioa, GPIO_OR);
gpio_set_pu(GPIOA, 0, 16, ~soff_gpio_config.gpioa, GPIO_AND);
gpio_set_pd(GPIOA, 0, 16, ~soff_gpio_config.gpioa, GPIO_AND);
gpio_die(GPIOA, 0, 16, ~soff_gpio_config.gpioa, GPIO_AND);
gpio_dieh(GPIOA, 0, 16, ~soff_gpio_config.gpioa, GPIO_AND);
gpio_dir(GPIOB, 0, 16, soff_gpio_config.gpiob, GPIO_OR);
gpio_set_pu(GPIOB, 0, 16, ~soff_gpio_config.gpiob, GPIO_AND);
gpio_set_pd(GPIOB, 0, 16, ~soff_gpio_config.gpiob, GPIO_AND);
gpio_die(GPIOB, 0, 16, ~soff_gpio_config.gpiob, GPIO_AND);
gpio_dieh(GPIOB, 0, 16, ~soff_gpio_config.gpiob, GPIO_AND);
gpio_dir(GPIOC, 0, 16, soff_gpio_config.gpioc, GPIO_OR);
gpio_set_pu(GPIOC, 0, 16, ~soff_gpio_config.gpioc, GPIO_AND);
gpio_set_pd(GPIOC, 0, 16, ~soff_gpio_config.gpioc, GPIO_AND);
gpio_die(GPIOC, 0, 16, ~soff_gpio_config.gpioc, GPIO_AND);
gpio_dieh(GPIOC, 0, 16, ~soff_gpio_config.gpioc, GPIO_AND);
gpio_dir(GPIOD, 0, 16, soff_gpio_config.gpiod, GPIO_OR);
gpio_set_pu(GPIOD, 0, 16, ~soff_gpio_config.gpiod, GPIO_AND);
gpio_set_pd(GPIOD, 0, 16, ~soff_gpio_config.gpiod, GPIO_AND);
gpio_die(GPIOD, 0, 16, ~soff_gpio_config.gpiod, GPIO_AND);
gpio_dieh(GPIOD, 0, 16, ~soff_gpio_config.gpiod, GPIO_AND);
gpio_dir(GPIOE, 0, 16, soff_gpio_config.gpioe, GPIO_OR);
gpio_set_pu(GPIOE, 0, 16, ~soff_gpio_config.gpioe, GPIO_AND);
gpio_set_pd(GPIOE, 0, 16, ~soff_gpio_config.gpioe, GPIO_AND);
gpio_die(GPIOE, 0, 16, ~soff_gpio_config.gpioe, GPIO_AND);
gpio_dieh(GPIOE, 0, 16, ~soff_gpio_config.gpioe, GPIO_AND);
gpio_dir(GPIOG, 0, 16, soff_gpio_config.gpiog, GPIO_OR);
gpio_set_pu(GPIOG, 0, 16, ~soff_gpio_config.gpiog, GPIO_AND);
gpio_set_pd(GPIOG, 0, 16, ~soff_gpio_config.gpiog, GPIO_AND);
gpio_die(GPIOG, 0, 16, ~soff_gpio_config.gpiog, GPIO_AND);
gpio_dieh(GPIOG, 0, 16, ~soff_gpio_config.gpiog, GPIO_AND);
gpio_dir(GPIOP, 0, 1, soff_gpio_config.gpiop, GPIO_OR);
gpio_set_pu(GPIOP, 0, 1, ~soff_gpio_config.gpiop, GPIO_AND);
gpio_set_pd(GPIOP, 0, 1, ~soff_gpio_config.gpiop, GPIO_AND);
gpio_die(GPIOP, 0, 1, ~soff_gpio_config.gpiop, GPIO_AND);
gpio_dieh(GPIOP, 0, 1, ~soff_gpio_config.gpiop, GPIO_AND);
if (soff_gpio_config.gpiousb) {
usb_iomode(1);
if (soff_gpio_config.gpiousb & BIT(0)) {
gpio_set_pull_up(IO_PORT_DP, 0);
gpio_set_pull_down(IO_PORT_DP, 0);
gpio_set_direction(IO_PORT_DP, 1);
gpio_set_die(IO_PORT_DP, 0);
gpio_set_dieh(IO_PORT_DP, 0);
}
if (soff_gpio_config.gpiousb & BIT(1)) {
gpio_set_pull_up(IO_PORT_DM, 0);
gpio_set_pull_down(IO_PORT_DM, 0);
gpio_set_direction(IO_PORT_DM, 1);
gpio_set_die(IO_PORT_DM, 0);
gpio_set_dieh(IO_PORT_DM, 0);
}
}
}

292
cpu/br28/power/power_trim.c Normal file
View File

@ -0,0 +1,292 @@
#include "asm/power_interface.h"
#include "asm/adc_api.h"
#include "app_config.h"
#include "includes.h"
#include "stdlib.h"
__attribute__((noinline))
AT(.volatile_ram_code)
static u8 wiovdd_trim(u8 trim, s16 *adc_wiovdd_voltage)
{
u32 wiovdd_lev = 7;
u32 miovdd_lev = 0;
P33_CON_SET(P3_ANA_CON5, 3, 3, wiovdd_lev);
delay(215);//延时50us
P33_CON_SET(P3_ANA_CON5, 0, 3, miovdd_lev);
delay(430);
if (trim) {
for (; wiovdd_lev > 3; wiovdd_lev--) {
P33_CON_SET(P3_ANA_CON5, 3, 3, wiovdd_lev);
delay(700);//延时50us
adc_wiovdd_voltage[wiovdd_lev] = get_vddio_voltage();;
}
for (int i = 3; i >= 0; i--) {
adc_wiovdd_voltage[i] = adc_wiovdd_voltage[i + 1] - 200;
}
}
return 0;
}
__attribute__((noinline))
AT(.volatile_ram_code)
u8 miovdd_trim(u8 trim, s16 *adc_miovdd_voltage)
{
u32 wiovdd_lev = 0;
u32 miovdd_lev = 7;
P33_CON_SET(P3_ANA_CON5, 0, 3, miovdd_lev);
delay(430);
P33_CON_SET(P3_ANA_CON5, 3, 3, wiovdd_lev);
delay(215);//延时50us
if (trim) {
for (; miovdd_lev > 3; miovdd_lev--) {
P33_CON_SET(P3_ANA_CON5, 0, 3, miovdd_lev);
delay(700);//延时50us
adc_miovdd_voltage[miovdd_lev] = get_vddio_voltage();;
}
for (int i = 3; i >= 0; i--) {
adc_miovdd_voltage[i] = adc_miovdd_voltage[i + 1] - 200;
}
}
return 0;
}
__attribute__((noinline))
AT(.volatile_ram_code)
u32 iovdd_trim(u8 trim, u8 *miovdd_lev, u8 *wiovdd_lev)
{
const u32 m_iovdd_lev = P3_ANA_CON5 & 0xf;
if (trim == 0) {
return 1;
}
u32 check_vbat = get_vdd_voltage(AD_CH_VBAT) * 4;
printf("check_vbat = %d\n", check_vbat);
if (check_vbat < 3700) {
printf("%s %d\n", __func__, __LINE__);
*miovdd_lev = m_iovdd_lev | BIT(7);
*wiovdd_lev = m_iovdd_lev | BIT(7);
return 0;
}
local_irq_disable();
const u32 lvd_con = P3_VLVD_CON;
P3_VLVD_CON &= ~BIT(2);
delay(100);
P3_VLVD_CON &= ~BIT(0); //关闭lvd
s16 adc_wiovdd_voltage[8];
s16 adc_miovdd_voltage[8];
miovdd_trim(trim, adc_miovdd_voltage);
wiovdd_trim(trim, adc_wiovdd_voltage);
if (lvd_con & BIT(0)) {
P3_VLVD_CON |= BIT(0);//en
delay(3);
P3_VLVD_CON |= BIT(2);//oe
}
local_irq_enable();
int miovdd_voltage = m_iovdd_lev * 200 + 2000;
u32 min_diff = -1;
int mlev = 0;
for (int i = 7; i >= 0; i--) {
u32 diff = abs(miovdd_voltage - adc_miovdd_voltage[i]);
if (diff < min_diff) {
mlev = i;
min_diff = diff;
}
}
*miovdd_lev = mlev;
u32 wlev = 0;
min_diff = -1;
for (int i = 7; i >= 0; i--) {
u32 diff = abs(adc_miovdd_voltage[mlev] - adc_wiovdd_voltage[i]);
if (diff < min_diff) {
wlev = i;
min_diff = diff;
}
}
*wiovdd_lev = wlev;
for (u8 i = 0; i < 8; i++) {
printf("adc_wiovdd_voltage[%d] = %d\n", i, adc_wiovdd_voltage[i]);
printf("adc_miovdd_voltage[%d] = %d\n", i, adc_miovdd_voltage[i]);
}
return 0;
}
static u8 wvdd_trim(u8 trim)
{
u8 wvdd_lev = 0;
wvdd_lev = 0;
int v = 0;
u8 err = 0;
if (trim) {
v = get_wvdd_level_trim();
if (v == 0) {
//0.65v
wvdd_lev = 0b0011;
} else if (v == 1) {
//0.7v
wvdd_lev = 0b0100;
} else if (v == 2) {
//0.75v
wvdd_lev = 0b0101;
} else {
//0.8v
//wvdd_lev = 0b0110;
WVDD_VOL_SEL(wvdd_lev);
WVDD_LOAD_EN(1);
WLDO06_EN(1);
delay(2000);//1ms
do {
WVDD_VOL_SEL(wvdd_lev);
delay(2000);//1ms * n
v = get_vdd_voltage(AD_CH_WVDD);
if (v > WVDD_VOL_TRIM) {
break;
}
wvdd_lev ++;
} while (wvdd_lev < WVDD_LEVEL_MAX);
WVDD_LOAD_EN(0);
WLDO06_EN(0);
u8 min = (WVDD_VOL_TRIM - WVDD_VOL_MIN) / WVDD_VOL_STEP - 2;
u8 max = (WVDD_VOL_TRIM - WVDD_VOL_MIN) / WVDD_VOL_STEP + 2;
if (!(wvdd_lev >= min && wvdd_lev <= max)) {
wvdd_lev = WVDD_LEVEL_DEFAULT;
err = 1;
}
}
//update_wvdd_trim_level(wvdd_lev);
} else {
wvdd_lev = get_wvdd_trim_level();
}
printf("trim: %d, wvdd_lev: %d, v: %d, err: %d\n", trim, wvdd_lev, v, err);
M2P_WDVDD = wvdd_lev;
if (err) {
return WVDD_LEVEL_ERR;
}
return wvdd_lev;
}
static u8 pvdd_trim(u8 trim)
{
/* return 0; */
u32 v = 0;
u8 lev_high_now = PVDD_LEVEL_DEFAULT;
u8 err = 0;
if (trim) {
PVDD_LEVEL_HIGH_NOW(PVDD_LEVEL_REF);
delay(2000);//1ms
v = get_vdd_voltage(AD_CH_PVDD);//adc_get_voltage_preemption(AD_CH_PVDD);
if ((v < (PVDD_VOL_REF - 2 * PVDD_VOL_STEP)) || (v > (PVDD_VOL_REF + 2 * PVDD_VOL_STEP))) {
lev_high_now = PVDD_LEVEL_DEFAULT;
M2P_PVDD_LEVEL_SLEEP_TRIM = PVDD_LEVEL_SLEEP;
err = 1;
} else {
M2P_PVDD_LEVEL_SLEEP_TRIM = (PVDD_LEVEL_REF - (v - PVDD_VOL_SLEEP) / PVDD_VOL_STEP);
lev_high_now = M2P_PVDD_LEVEL_SLEEP_TRIM + (PVDD_VOL_HIGH_NOW - PVDD_VOL_SLEEP) / PVDD_VOL_STEP;
}
} else {
lev_high_now = get_pvdd_trim_level();
M2P_PVDD_LEVEL_SLEEP_TRIM = get_pvdd_level() - (PVDD_VOL_HIGH_NOW - PVDD_VOL_SLEEP) / PVDD_VOL_STEP;
}
#if (!PMU_NEW_FLOW)
if (get_pvdd_dcdc_cfg()) {
//外接dcdcpvdd配置为3档
lev_high_now = 3;
}
#endif
PVDD_LEVEL_HIGH_NOW(lev_high_now);
delay(2000);
PVDD_AUTO_PRD(0x3);
PVDD_LEVEL_AUTO(0x1);
PVDD_LEVEL_LOW(M2P_WDVDD);
#if PMU_NEW_FLOW
if (get_pvdd_dcdc_cfg()) {
power_set_pvdd_mode(PWR_PVDD_DCDC);
}
#endif
printf("trim: %d, pvdd_vol_ref: %d, pvdd_level_high_now_trim: %d, pvdd_level_sleep_trim: %d, pvdd_level_lev_l_trim: %d, err: %d\n", \
trim, v, lev_high_now, M2P_PVDD_LEVEL_SLEEP_TRIM, M2P_WDVDD, err);
cap_rch_enable();
if (err) {
return PVDD_LEVEL_ERR;
}
return lev_high_now;
}
void volatage_trim_init()
{
/* trim wvdd */
printf("lvd_con = 0x%x\n", P3_VLVD_CON);
u8 trim = load_pmu_trim_value_from_vm();
u8 wvdd_lev = 0;
u8 pvdd_lev = 0;
extern bool vm_need_recover(void);
if (vm_need_recover()) { // 升级完后重新trim
trim = 0xff;
}
printf("trim = 0x%x\n", trim);
wvdd_lev = wvdd_trim((trim & TRIM_WVDD) ? 1 : 0);
pvdd_lev = pvdd_trim((trim & TRIM_PVDD) ? 1 : 0);
u8 miovdd_lev = 0;
u8 wiovdd_lev = 0;
if (trim & TRIM_IOVDD) {
u8 trim_succ = iovdd_trim(trim, &miovdd_lev, &wiovdd_lev);
} else {
miovdd_lev = get_miovdd_trim_level();
wiovdd_lev = get_wiovdd_trim_level();
}
if (trim) {
if ((wvdd_lev != WVDD_LEVEL_ERR) && (pvdd_lev != PVDD_LEVEL_ERR)) {
store_pmu_trim_value_to_vm(wvdd_lev, pvdd_lev, miovdd_lev, wiovdd_lev);
}
}
printf("miovdd_lev = %x\n", miovdd_lev);
printf("wiovdd_lev = %x\n", wiovdd_lev);
P33_CON_SET(P3_ANA_CON5, 0, 3, miovdd_lev);
P33_CON_SET(P3_ANA_CON5, 3, 3, 0);
}