KT25-0812_82A-UART/apps/common/charge_box/chgbox_handshake.c

301 lines
8.7 KiB
C
Raw Permalink Normal View History

2025-08-12 10:09:23 +00:00
#include "gpio.h"
#include "app_config.h"
#include "system/includes.h"
#include "chgbox_ctrl.h"
#include "asm/adc_api.h"
#include "chgbox_box.h"
#include "device/chargebox.h"
#include "chgbox_handshake.h"
#if (TCFG_CHARGE_BOX_ENABLE && TCFG_HANDSHAKE_ENABLE)
#define LOG_TAG_CONST APP_CHGBOX
#define LOG_TAG "[CHG_HS]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
extern void delay_2ms(int cnt);
/*------------------------------------------------------------------------------------*/
/**@brief 关闭所有中断使能
@param
@return
@note 便
*/
/*------------------------------------------------------------------------------------*/
static u8 irq_ie_tab[10];
void chgbox_irq_disable_backup()
{
u8 i;
u8 x, y;
local_irq_disable();
memset(irq_ie_tab, 0, sizeof(irq_ie_tab) / sizeof(irq_ie_tab[0]));
for (i = 0; i < MAX_IRQ_ENTRY_NUM; i++) {
if (irq_read(i)) {
x = i / 8;
y = i % 8;
irq_ie_tab[x] |= BIT(y);
}
}
for (i = 0; i < MAX_IRQ_ENTRY_NUM; i++) {
irq_disable(i);
}
local_irq_enable();
}
/*------------------------------------------------------------------------------------*/
/**@brief 中断使能恢复
@param
@return
@note chgbox_irq_disable_backup关闭的中断
*/
/*------------------------------------------------------------------------------------*/
void chgbox_irq_enable_revert()
{
u8 i;
u8 x, y;
local_irq_disable();
for (i = 0; i < MAX_IRQ_ENTRY_NUM; i++) {
x = i / 8;
y = i % 8;
if (irq_ie_tab[x] & BIT(y)) {
irq_enable(i);
}
}
local_irq_enable();
}
//关于handshake部分
//////////////////////////////////////////////////////////////////////////
void chgbox_timer2_delay_us(u8 us);
struct _hs_hdl hs_ctrl = {
.port = CHGBOX_HANDSHAKE_IO, //初始化IO
.send_delay_us = chgbox_timer2_delay_us, //注册延时函数
};
/*------------------------------------------------------------------------------------*/
/**@brief lighting握手初始化
@param
@return
@note io及注册延时
*/
/*------------------------------------------------------------------------------------*/
void chgbox_handshake_init(void)
{
//部分封装与其他IO绑定在一起,注意设置成高阻
gpio_direction_input(IO_PORTC_07);
gpio_set_die(IO_PORTC_07, 0);
gpio_set_pull_down(IO_PORTC_07, 0);
gpio_set_pull_up(IO_PORTC_07, 0);
handshake_ctrl_init(&hs_ctrl);
}
u8 hs_cur_sys_clk = 0; //当前时钟匹配值
u32 hs_small_clk = 0; //小于48m的系统时钟,记录,用来恢复
u16 delay_tap[HS_DELAY_240M + 1][HS_DELAY_16US + 1] = {
19, 39, 52, 141, 158, 309, 355,//48m
23, 45, 59, 146, 165, 315, 359,//60m
27, 51, 66, 148, 170, 318, 367,//80m
30, 55, 73, 151, 173, 320, 369,//96m
32, 58, 75, 154, 177, 323, 370,//120m
37, 60, 79, 157, 178, 325, 374,//160m
38, 62, 82, 158, 179, 327, 376,//192m
40, 64, 84, 159, 184, 328, 378,//240m
};
/*------------------------------------------------------------------------------------*/
/**@brief 获取当前的时钟,设置对应的表值
@param
@return
@note delay_tap
*/
/*------------------------------------------------------------------------------------*/
void set_hs_cur_sys_clk(void)
{
u32 cur_clock = 0;
cur_clock = clk_get("sys");
if (cur_clock < 48000000) { //小于48m时转成48m结束后恢复原来的时钟
hs_small_clk = cur_clock;
clk_set("sys", 48 * 1000000L);
hs_cur_sys_clk = HS_DELAY_48M;
puts("rest 48m\n");
} else {
switch (cur_clock) {
case 48000000:
hs_cur_sys_clk = HS_DELAY_48M;
break;
case 60000000:
hs_cur_sys_clk = HS_DELAY_60M;
break;
case 80000000:
hs_cur_sys_clk = HS_DELAY_80M;
break;
case 96000000:
hs_cur_sys_clk = HS_DELAY_96M;
break;
case 120000000:
hs_cur_sys_clk = HS_DELAY_120M;
break;
case 160000000:
hs_cur_sys_clk = HS_DELAY_160M;
break;
case 192000000:
hs_cur_sys_clk = HS_DELAY_192M;
break;
case 240000000:
hs_cur_sys_clk = HS_DELAY_240M;
break;
}
}
}
/*------------------------------------------------------------------------------------*/
/**@brief 握手后重设置时钟
@param
@return
@note
*/
/*------------------------------------------------------------------------------------*/
void after_handshake_resume_small_clk(void)
{
u32 cur_clock = 0;
if (hs_small_clk) {
clk_set("sys", hs_small_clk);
hs_small_clk = 0;//清0
cur_clock = clk_get("sys");
printf("after handshake app :%d\n", cur_clock);
}
}
/*------------------------------------------------------------------------------------*/
/**@brief lighting握手延时
@param
@return
@note us级延时
*/
/*------------------------------------------------------------------------------------*/
SEC(.chargebox_code)
void chgbox_timer2_delay_us(u8 us)
{
//delay 值要根据不同的频率去调整小于48m的要先设置48m方便延时
switch (us) {
case HS_DELAY_2US:
JL_TIMER2->PRD = delay_tap[hs_cur_sys_clk][HS_DELAY_2US];//24*2;
break;
case HS_DELAY_3US:
JL_TIMER2->PRD = delay_tap[hs_cur_sys_clk][HS_DELAY_3US];//24*3;
break;
case HS_DELAY_4US:
JL_TIMER2->PRD = delay_tap[hs_cur_sys_clk][HS_DELAY_4US];//24*4;
break;
case HS_DELAY_7US:
JL_TIMER2->PRD = delay_tap[hs_cur_sys_clk][HS_DELAY_7US];//24*7;
break;
case HS_DELAY_8US:
JL_TIMER2->PRD = delay_tap[hs_cur_sys_clk][HS_DELAY_8US];//24*8;
break;
case HS_DELAY_14US:
JL_TIMER2->PRD = delay_tap[hs_cur_sys_clk][HS_DELAY_14US];//24*14;
break;
case HS_DELAY_16US:
JL_TIMER2->PRD = delay_tap[hs_cur_sys_clk][HS_DELAY_16US];//24*16;
break;
}
JL_TIMER2->CON = BIT(0) | BIT(3) | BIT(14); //1分频,osc时钟,24m24次就1us
while (!(JL_TIMER2->CON & BIT(15))); //等pending
JL_TIMER2->CON = 0;
}
/*------------------------------------------------------------------------------------*/
/**@brief lighting握手
@param
@return
@note
*/
/*------------------------------------------------------------------------------------*/
void chgbox_handshake_run_app(void)
{
delay_2ms(2);
chgbox_irq_disable_backup();
set_hs_cur_sys_clk();
handshake_send_app(HS_CMD0);
chgbox_irq_enable_revert();
delay_2ms(2);
chgbox_irq_disable_backup();
set_hs_cur_sys_clk();
handshake_send_app(HS_CMD1);
chgbox_irq_enable_revert();
delay_2ms(2);
chgbox_irq_disable_backup();
set_hs_cur_sys_clk();
handshake_send_app(HS_CMD2);
chgbox_irq_enable_revert();
delay_2ms(2);
chgbox_irq_disable_backup();
set_hs_cur_sys_clk();
handshake_send_app(HS_CMD3);
chgbox_irq_enable_revert();
after_handshake_resume_small_clk();
}
//握手n次处理
static u8 chgbox_hs_repeat_times = 0; //重复次数
static int hs_timer;
/*------------------------------------------------------------------------------------*/
/**@brief lighting重复握手
@param null
@return
@note
*/
/*------------------------------------------------------------------------------------*/
static void chgbox_handshake_deal(void *priv)
{
chgbox_handshake_run_app();
chgbox_hs_repeat_times--;
if (chgbox_hs_repeat_times == 0) {
sys_timer_del(hs_timer);
hs_timer = 0;
}
}
/*------------------------------------------------------------------------------------*/
/**@brief lighting重复握手初始化
@param times:
@return
@note
*/
/*------------------------------------------------------------------------------------*/
void chgbox_handshake_set_repeat(u8 times)
{
chgbox_hs_repeat_times = times;
if (chgbox_hs_repeat_times) {
if (hs_timer == 0) {
hs_timer = sys_timer_add(NULL, chgbox_handshake_deal, 2000);
}
} else {
if (hs_timer) {
sys_timer_del(hs_timer);
hs_timer = 0;
}
}
}
#endif