负载running触发逻辑功率板返回电压与V_On点比较,拉载速度从2秒变成100ms
短路模式增加持续发送启动指令,能稳定短路充电头 1. 修改工作电压下限从3000mV调整为500mV 2. 迁移Sink电压稳定确认参数到chrg_sink.h 3. 将chrg_sink_volt_judge函数实现电压判定逻辑 4. 在北向线程中简化chrg_sink_parse函数 5. 新增短路测试保活机制,定期补发WORK_START 6. 重构chrg_sink_work_init的寄存器配置逻辑 7. 新增docs/HC_DFCD_Protocol_V3_0.brd和hc_dfcd_protocol.opj文件
This commit is contained in:
@@ -28,11 +28,8 @@
|
|||||||
#define SOURCE_VOLT_RETRY_FRAMES 3U // Source电压持续超差后的重发确认帧数
|
#define SOURCE_VOLT_RETRY_FRAMES 3U // Source电压持续超差后的重发确认帧数
|
||||||
#define SOURCE_QC_MIN_VOLT_MV 5000U // QC2.0/QC3.0允许使用的最低目标电压
|
#define SOURCE_QC_MIN_VOLT_MV 5000U // QC2.0/QC3.0允许使用的最低目标电压
|
||||||
#define SOURCE_QC_SWITCH_ERROR 0x04U // Source协议或CC切换失败错误位
|
#define SOURCE_QC_SWITCH_ERROR 0x04U // Source协议或CC切换失败错误位
|
||||||
#define SINK_CURRENT_START_GRACE_MS 200U // Sink启动后暂不判断无电流的保护时间
|
|
||||||
#define SINK_VOLT_STABLE_ERROR_MV 2000U // Sink实际电压与协议目标电压的最大允许误差
|
#define SINK_VOLT_STABLE_ERROR_MV 2000U // Sink实际电压与协议目标电压的最大允许误差
|
||||||
#define SINK_VOLT_5V_TARGET_MV 5000U // VSafe5V目标电压,需延长稳定确认时间
|
/* Sink电压稳定确认参数已迁移至chrg_sink.h,供chrg_sink_volt_judge使用。 */
|
||||||
#define SINK_VOLT_CONFIRM_NORMAL_COUNT 5U // 非5V目标连续有效电压确认帧数
|
|
||||||
#define SINK_VOLT_CONFIRM_5V_COUNT 15U // 5V目标连续有效电压确认帧数,避免把握手阶段VSafe5V误判为协议稳定
|
|
||||||
|
|
||||||
/*****************************************************************
|
/*****************************************************************
|
||||||
函数名称: chrg_source_apply_protocol_voltage_rule
|
函数名称: chrg_source_apply_protocol_voltage_rule
|
||||||
@@ -84,22 +81,6 @@ static rt_bool_t chrg_sink_voltage_is_stable(rt_uint16_t actual_volt_mv,
|
|||||||
RT_TRUE : RT_FALSE;
|
RT_TRUE : RT_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************
|
|
||||||
函数名称: chrg_sink_voltage_confirm_count
|
|
||||||
函数描述: 根据Sink协议目标电压选择进入RUNING前所需的连续稳定帧数
|
|
||||||
输入参数: target_volt_mv:当前协议申请的目标电压,单位mV
|
|
||||||
输出参数: -
|
|
||||||
返回说明: 5V目标返回延长确认帧数,其它目标返回普通确认帧数
|
|
||||||
其它说明: 快充协议切换时总线会先经过VSafe5V;当目标本身也是5V时,
|
|
||||||
单凭电压值无法区分过渡阶段和协议稳定阶段,因此增加确认时间,
|
|
||||||
防止电子负载提前启动后导致协议板复位
|
|
||||||
*****************************************************************/
|
|
||||||
static rt_uint8_t chrg_sink_voltage_confirm_count(rt_uint16_t target_volt_mv)
|
|
||||||
{
|
|
||||||
return (target_volt_mv == SINK_VOLT_5V_TARGET_MV) ?
|
|
||||||
SINK_VOLT_CONFIRM_5V_COUNT : SINK_VOLT_CONFIRM_NORMAL_COUNT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************
|
/*****************************************************************
|
||||||
函数名称: chrg_source_voltage_control
|
函数名称: chrg_source_voltage_control
|
||||||
函数描述: 根据目标电压与实际电压统一控制Source电压下发和重试
|
函数描述: 根据目标电压与实际电压统一控制Source电压下发和重试
|
||||||
@@ -231,110 +212,29 @@ void chrg_source_setting(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
|
|||||||
|
|
||||||
/*****************************************************************
|
/*****************************************************************
|
||||||
函数名称: chrg_sink_parse
|
函数名称: chrg_sink_parse
|
||||||
函数描述: 解析北向负载板回码并根据电压、电流反馈驱动Sink状态机
|
函数描述: 解析北向负载板0x20回码,提取D+/D-电压到VZ/VF
|
||||||
输入参数: frame_data:完整北向回码 idx:当前通道 pSW:通道控制结构体
|
输入参数: frame_data:完整北向回码 idx:当前通道 pSW:通道控制结构体
|
||||||
pNOR:北向总控结构体
|
pNOR:北向总控结构体
|
||||||
输出参数: 更新VZ、VF、低压计数、稳定电压计数、无电流计数及sink.work_mode
|
输出参数: 更新pSW->VZ(D+)、pSW->VF(D-)
|
||||||
返回说明: -
|
返回说明: -
|
||||||
其它说明: 电压连续低于门槛进入LOW;掉电处理恢复副继电器后,电压重新
|
其它说明: Sink电压状态机判定已迁移至chrg_sink_volt_judge,
|
||||||
出现时先重设协议和CC;一帧有效电压达到目标附近即进入RUNING
|
由北向轮询线程基于eload.c更新的Now_voltage驱动
|
||||||
*****************************************************************/
|
*****************************************************************/
|
||||||
void chrg_sink_parse(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
|
void chrg_sink_parse(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
|
||||||
struct chrg_switch_t *pSW, struct chrg_north_t *pNOR)
|
struct chrg_switch_t *pSW, struct chrg_north_t *pNOR)
|
||||||
{
|
{
|
||||||
rt_uint16_t volt_mv = ((frame_data[4] << 8) | frame_data[5]) * 10;
|
|
||||||
rt_uint8_t stable_confirm_count;
|
|
||||||
static rt_uint8_t volt_low[TOTAL_SOU_CHS] = {0};
|
|
||||||
static rt_uint8_t no_curr[TOTAL_SOU_CHS] = {0};
|
|
||||||
static rt_uint8_t volt_set_ok[TOTAL_SOU_CHS] = {0};
|
|
||||||
static rt_uint8_t volt_stable_count[TOTAL_SOU_CHS] = {0};
|
|
||||||
static rt_tick_t running_start_tick[TOTAL_SOU_CHS] = {0};
|
|
||||||
|
|
||||||
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
|
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
stable_confirm_count = chrg_sink_voltage_confirm_count(
|
|
||||||
pSW->sink.pro_loadv);
|
|
||||||
|
|
||||||
pSW->VZ = ((frame_data[14] << 8) | frame_data[15]);
|
pSW->VZ = ((frame_data[14] << 8) | frame_data[15]);
|
||||||
pSW->VF = ((frame_data[16] << 8) | frame_data[17]);
|
pSW->VF = ((frame_data[16] << 8) | frame_data[17]);
|
||||||
|
|
||||||
#if NORTH_SINK_DEBUG
|
#if NORTH_SINK_DEBUG
|
||||||
LOG_D("Sink[%d] real volt: %d mV", idx, volt_mv);
|
LOG_D("Sink[%d] real volt: %d mV", idx,
|
||||||
|
((frame_data[4] << 8) | frame_data[5]) * 10);
|
||||||
#endif
|
#endif
|
||||||
|
(void)pNOR;
|
||||||
if(pSW->sink.On_work == 1 && pSW->sink.test.test_mode == 0) {
|
|
||||||
if (volt_mv <= WORK_MIN_VOLT) { // 电压过低,禁止进入工作状态机
|
|
||||||
volt_stable_count[idx] = 0;
|
|
||||||
if (volt_set_ok[idx] == 1) {
|
|
||||||
if (++volt_low[idx] >= 50) {
|
|
||||||
volt_set_ok[idx] = 0;
|
|
||||||
no_curr[idx] = 0;
|
|
||||||
//pSW->sink.work_mode = SINK_WORK_LOW;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{ // 电压稳定时执行工作状态机(继电器/工作模式切换)
|
|
||||||
volt_low[idx] = 0;
|
|
||||||
volt_set_ok[idx] = 1;
|
|
||||||
pSW->change_flag = 0;
|
|
||||||
if (pSW->sink.work_mode == SINK_WORK_LOW_MONITOR) {
|
|
||||||
/* 副继电器恢复后首次重新检测到输入电压,只启动协议重握手。
|
|
||||||
* 当前回码不计入稳定电压次数,防止跳过协议设置直接带载。 */
|
|
||||||
volt_stable_count[idx] = 0;
|
|
||||||
no_curr[idx] = 0;
|
|
||||||
//pSW->sub = IDX_SET_SINK_CC_BEFORE_PD;
|
|
||||||
pSW->sink.work_mode = SINK_WORK_WAIT;
|
|
||||||
} else if ((pSW->sink.work_mode == SINK_WORK_LOW) ||
|
|
||||||
(pSW->sink.work_mode == SINK_WORK_LOW_AUX_WAIT)) {
|
|
||||||
/* 掉电安全批次完成前,即使收到残留回码也不得进入RUNING。 */
|
|
||||||
volt_stable_count[idx] = 0;
|
|
||||||
no_curr[idx] = 0;
|
|
||||||
}
|
|
||||||
else if (chrg_sink_voltage_is_stable(volt_mv,
|
|
||||||
pSW->sink.pro_loadv)) {
|
|
||||||
if ((pSW->sink.work_mode != SINK_WORK_RUNING) &&
|
|
||||||
(pSW->sink.work_mode != SINK_WORK_LOAD_STANDBY)) {
|
|
||||||
if (volt_stable_count[idx] < stable_confirm_count) {
|
|
||||||
volt_stable_count[idx]++;
|
|
||||||
}
|
|
||||||
if (volt_stable_count[idx] >= stable_confirm_count) {
|
|
||||||
/* 回码已经过CRC、ID、命令和配置版本校验,并连续达到当前
|
|
||||||
* 目标对应的确认帧数;5V采用更长窗口过滤VSafe5V过渡阶段。 */
|
|
||||||
volt_stable_count[idx] = 0;
|
|
||||||
pSW->sink.work_mode = SINK_WORK_RUNING;
|
|
||||||
running_start_tick[idx] = rt_tick_get();
|
|
||||||
no_curr[idx] = 0;
|
|
||||||
}
|
|
||||||
} else if (pSW->sink.work_mode == SINK_WORK_LOAD_STANDBY) {
|
|
||||||
/* 协议保持在线但电子负载主动停止,不执行无电流重试。 */
|
|
||||||
volt_stable_count[idx] = 0;
|
|
||||||
no_curr[idx] = 0;
|
|
||||||
} else if ((pSW->Now_current > 200) ||
|
|
||||||
(pSW->sink.loadc < 200)) {
|
|
||||||
volt_stable_count[idx] = 0;
|
|
||||||
no_curr[idx] = 0;
|
|
||||||
} else if ((rt_tick_t)(rt_tick_get() - running_start_tick[idx]) >=
|
|
||||||
rt_tick_from_millisecond(SINK_CURRENT_START_GRACE_MS)) {
|
|
||||||
volt_stable_count[idx] = 0;
|
|
||||||
if (++no_curr[idx] >= 2) {
|
|
||||||
pSW->sink.work_mode = SINK_WORK_WAIT;
|
|
||||||
no_curr[idx] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
volt_stable_count[idx] = 0;
|
|
||||||
no_curr[idx] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
volt_low[idx] = 0;
|
|
||||||
no_curr[idx] = 0;
|
|
||||||
volt_set_ok[idx] = 0;
|
|
||||||
volt_stable_count[idx] = 0;
|
|
||||||
}
|
|
||||||
chrg_sink_work(idx,pSW);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct chrg_north_t chrgnorth = {
|
struct chrg_north_t chrgnorth = {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#define LEN_FRAME_HEAD (4) // [帧长, 0x00, id, 命令]
|
#define LEN_FRAME_HEAD (4) // [帧长, 0x00, id, 命令]
|
||||||
#define MIN_FRAME_LENGTH (5) // 帧最短5字节
|
#define MIN_FRAME_LENGTH (5) // 帧最短5字节
|
||||||
#define WORK_MIN_VOLT 3000 // 工作电压下限,单位mV
|
#define WORK_MIN_VOLT 500 // 工作电压下限,单位mV
|
||||||
#define NORTH_FRAME_DEBUG 0x00 // 北向UART原始收发帧
|
#define NORTH_FRAME_DEBUG 0x00 // 北向UART原始收发帧
|
||||||
#define NORTH_SOURCE_DEBUG 0x01 // Source协议解析及组帧
|
#define NORTH_SOURCE_DEBUG 0x01 // Source协议解析及组帧
|
||||||
#define NORTH_SINK_DEBUG 0x00 // Sink协议解析及组帧
|
#define NORTH_SINK_DEBUG 0x00 // Sink协议解析及组帧
|
||||||
|
|||||||
@@ -992,8 +992,17 @@ void chrg_roll_nor_thread_entry (void *data)
|
|||||||
* 协议切换等待只推进时间状态,不发送串口命令。该检查位于enable
|
* 协议切换等待只推进时间状态,不发送串口命令。该检查位于enable
|
||||||
* 过滤前,使停止或角色切换后的通道也能及时清理残留事务记录。
|
* 过滤前,使停止或角色切换后的通道也能及时清理残留事务记录。
|
||||||
*/
|
*/
|
||||||
source_waiting = chrg_roll_nor_source_wait_process(idx, pSW);
|
source_waiting = chrg_roll_nor_source_wait_process(idx, pSW);
|
||||||
sink_waiting = chrg_roll_nor_sink_wait_process(idx, pSW);
|
sink_waiting = chrg_roll_nor_sink_wait_process(idx, pSW);
|
||||||
|
|
||||||
|
/* 全通道Sink电压判定:使用eload实际电压Now_voltage与V_On比较,
|
||||||
|
* 判定后统一由chrg_sink_work执行;短路测试由该入口负责WORK_START保活。 */
|
||||||
|
for (i = 0; i < TOTAL_NOR_CHS; i++) {
|
||||||
|
struct chrg_switch_t *psw = &pNOR->sw[i];
|
||||||
|
if ((psw->id == ID_SINK) && psw->sink.On_work) {
|
||||||
|
(void)chrg_sink_volt_judge((eIDX_SOU_CH)i, psw);
|
||||||
|
}
|
||||||
|
}
|
||||||
rt_mutex_release(pTHR->mutex);
|
rt_mutex_release(pTHR->mutex);
|
||||||
if (state_work_ret != 0) {
|
if (state_work_ret != 0) {
|
||||||
/* 南向状态动作未成功入队时保留原状态,下轮重试且禁止北向先行。 */
|
/* 南向状态动作未成功入队时保留原状态,下轮重试且禁止北向先行。 */
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ static rt_uint32_t g_sink_unload_sample_seq[TOTAL_SOU_CHS] = {0};
|
|||||||
static rt_bool_t g_sink_unload_batch_confirmed[TOTAL_SOU_CHS] = {RT_FALSE};
|
static rt_bool_t g_sink_unload_batch_confirmed[TOTAL_SOU_CHS] = {RT_FALSE};
|
||||||
static rt_tick_t g_sink_unload_query_tick[TOTAL_SOU_CHS] = {0};
|
static rt_tick_t g_sink_unload_query_tick[TOTAL_SOU_CHS] = {0};
|
||||||
static rt_uint8_t g_sink_unload_confirm_count[TOTAL_SOU_CHS] = {0};
|
static rt_uint8_t g_sink_unload_confirm_count[TOTAL_SOU_CHS] = {0};
|
||||||
|
/* 记录各通道短路测试最近一次WORK_START的发送时间。 */
|
||||||
|
static rt_tick_t g_sink_short_start_tick[TOTAL_SOU_CHS] = {0};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
SINK_UNLOAD_NEXT_RUNNING = 0,
|
SINK_UNLOAD_NEXT_RUNNING = 0,
|
||||||
@@ -244,11 +246,10 @@ int sink_set_pd (rt_uint8_t pd, rt_uint8_t *buf)
|
|||||||
static int chrg_sink_work_init(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
|
static int chrg_sink_work_init(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
|
||||||
{
|
{
|
||||||
struct chrg_north_t *pNOR = &chrgnorth;
|
struct chrg_north_t *pNOR = &chrgnorth;
|
||||||
rt_uint16_t regs[5] = {REG_REL_ON, REG_CURRENT_OUT + 1,
|
rt_uint16_t regs[6];
|
||||||
REG_MODE, Eload_Start_V_ON, 0};
|
rt_uint16_t vals[6];
|
||||||
rt_uint16_t vals[5] = {FU_REL_ON, 0, 0, 0, 0};
|
|
||||||
rt_bool_t first_start;
|
rt_bool_t first_start;
|
||||||
rt_uint8_t count = 4U;
|
rt_uint8_t count;
|
||||||
|
|
||||||
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
|
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -256,17 +257,31 @@ static int chrg_sink_work_init(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
|
|||||||
/* COM进入INIT前已经设置On_work,使用原工作状态区分首次提交和后台重试。 */
|
/* COM进入INIT前已经设置On_work,使用原工作状态区分首次提交和后台重试。 */
|
||||||
first_start = (pSW->sink.work_mode != SINK_WORK_INIT_AUX_WAIT) ?
|
first_start = (pSW->sink.work_mode != SINK_WORK_INIT_AUX_WAIT) ?
|
||||||
RT_TRUE : RT_FALSE;
|
RT_TRUE : RT_FALSE;
|
||||||
vals[2] = pSW->CV_mode;
|
|
||||||
vals[3] = pSW->sink.volt_on <= 500 ? 500 : pSW->sink.volt_on;
|
|
||||||
if (pSW->sink.test.test_mode_old == SINK_TEST_SHORT) {
|
if (pSW->sink.test.test_mode_old == SINK_TEST_SHORT) {
|
||||||
regs[count] = ModbusRTU_ShortTest_CMD_MODE_FLAG;
|
/* 短路测试退出:先断开全部继电器,再打开辅助继电器,最后停止短路测试。 */
|
||||||
vals[count++] = ModbusRTU_DYNA_CMD_MODE_STOP;
|
regs[0] = REG_REL_ON; vals[0] = ALL_REL_OFF;
|
||||||
} else if (pSW->sink.test.test_mode_old == SINK_TEST_OCP) {
|
regs[1] = REG_REL_ON; vals[1] = FU_REL_ON;
|
||||||
regs[count] = ModbusRTU_OCPTest_CMD_MODE_FLAG;
|
regs[2] = REG_CURRENT_OUT + 1; vals[2] = 0;
|
||||||
vals[count++] = ModbusRTU_DYNA_CMD_MODE_STOP;
|
regs[3] = REG_MODE; vals[3] = pSW->CV_mode;
|
||||||
} else if (pSW->sink.test.test_mode_old == SINK_TEST_DYNA) {
|
regs[4] = Eload_Start_V_ON; vals[4] =
|
||||||
regs[count] = ModbusRTU_DYNA_CMD_MODE_FLAG;
|
(pSW->sink.volt_on <= 500) ? 500 : pSW->sink.volt_on;
|
||||||
vals[count++] = ModbusRTU_DYNA_CMD_MODE_STOP;
|
regs[5] = ModbusRTU_ShortTest_CMD_MODE_FLAG;
|
||||||
|
vals[5] = ModbusRTU_DYNA_CMD_MODE_STOP;
|
||||||
|
count = 6U;
|
||||||
|
} else {
|
||||||
|
regs[0] = REG_REL_ON; vals[0] = FU_REL_ON;
|
||||||
|
regs[1] = REG_CURRENT_OUT + 1; vals[1] = 0;
|
||||||
|
regs[2] = REG_MODE; vals[2] = pSW->CV_mode;
|
||||||
|
regs[3] = Eload_Start_V_ON; vals[3] =
|
||||||
|
(pSW->sink.volt_on <= 500) ? 500 : pSW->sink.volt_on;
|
||||||
|
count = 4U;
|
||||||
|
if (pSW->sink.test.test_mode_old == SINK_TEST_OCP) {
|
||||||
|
regs[count] = ModbusRTU_OCPTest_CMD_MODE_FLAG;
|
||||||
|
vals[count++] = ModbusRTU_DYNA_CMD_MODE_STOP;
|
||||||
|
} else if (pSW->sink.test.test_mode_old == SINK_TEST_DYNA) {
|
||||||
|
regs[count] = ModbusRTU_DYNA_CMD_MODE_FLAG;
|
||||||
|
vals[count++] = ModbusRTU_DYNA_CMD_MODE_STOP;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (chrg_sou_com_batch_submit(idx, regs, vals, count) != 0) {
|
if (chrg_sou_com_batch_submit(idx, regs, vals, count) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -814,16 +829,133 @@ static int chrg_sink_TEST_SHORT_ON(rt_uint8_t ch, struct chrg_switch_t *pSW)
|
|||||||
{
|
{
|
||||||
rt_uint16_t regs[3] = {ModbusRTU_ShortTest_Hold_Time,ModbusRTU_ShortTest_CMD_MODE_FLAG, REG_WORK};
|
rt_uint16_t regs[3] = {ModbusRTU_ShortTest_Hold_Time,ModbusRTU_ShortTest_CMD_MODE_FLAG, REG_WORK};
|
||||||
rt_uint16_t vals[3] = {0,0,0};
|
rt_uint16_t vals[3] = {0,0,0};
|
||||||
if(pSW->sink.test.short_test.set_mode == 0)
|
/* 外部工程固定短路测试保持60秒且不带载。 */
|
||||||
{
|
vals[0] = 60000;
|
||||||
vals[0] = pSW->sink.test.short_test.hold_time;
|
vals[1] = ModbusRTU_DYNA_CMD_MODE_RUN_NO_CURR;
|
||||||
vals[1] = ModbusRTU_DYNA_CMD_MODE_RUN_NO_CURR;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
vals[1] = ModbusRTU_DYNA_CMD_MODE_RUN_ALWAYS_KEPP;
|
|
||||||
}
|
|
||||||
vals[2] = WORK_START;
|
vals[2] = WORK_START;
|
||||||
return chrg_sou_com_batch_submit((eIDX_SOU_CH)ch, regs, vals, 3);
|
if (chrg_sou_com_batch_submit((eIDX_SOU_CH)ch, regs, vals, 3) == 0) {
|
||||||
|
g_sink_short_start_tick[ch] = rt_tick_get();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 短路测试保持期间只补发WORK_START,避免重复写入测试配置并堆积批次。 */
|
||||||
|
static int chrg_sink_TEST_SHORT_KEEPALIVE(rt_uint8_t ch)
|
||||||
|
{
|
||||||
|
rt_uint16_t reg = REG_WORK;
|
||||||
|
rt_uint16_t val = WORK_START;
|
||||||
|
rt_tick_t now = rt_tick_get();
|
||||||
|
|
||||||
|
if ((rt_tick_t)(now - g_sink_short_start_tick[ch]) <
|
||||||
|
rt_tick_from_millisecond(SINK_SHORT_START_INTERVAL_MS)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (chrg_sou_com_batch_is_pending((eIDX_SOU_CH)ch)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (chrg_sou_com_batch_submit((eIDX_SOU_CH)ch, ®, &val, 1U) == 0) {
|
||||||
|
g_sink_short_start_tick[ch] = now;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************
|
||||||
|
函数名称: chrg_sink_voltage_confirm_count
|
||||||
|
函数描述: 根据Sink协议目标电压选择进入RUNING前所需的连续稳定帧数
|
||||||
|
输入参数: target_volt_mv:当前协议申请的目标电压,单位mV
|
||||||
|
输出参数: -
|
||||||
|
返回说明: 5V目标返回延长确认帧数,其它目标返回普通确认帧数
|
||||||
|
其它说明: 由chrg_sink_volt_judge调用
|
||||||
|
*****************************************************************/
|
||||||
|
static rt_uint8_t chrg_sink_voltage_confirm_count(rt_uint16_t target_volt_mv)
|
||||||
|
{
|
||||||
|
return (target_volt_mv == SINK_VOLT_5V_TARGET_MV) ?
|
||||||
|
SINK_VOLT_CONFIRM_5V_COUNT : SINK_VOLT_CONFIRM_NORMAL_COUNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************
|
||||||
|
函数名称: chrg_sink_volt_judge
|
||||||
|
函数描述: 使用南向功率板实际电压Now_voltage与V_On比较,驱动负载进入RUNING
|
||||||
|
输入参数: idx:南向通道 pSW:通道控制结构体
|
||||||
|
输出参数: 更新sink.work_mode并调用chrg_sink_work
|
||||||
|
返回说明: 0:处理完成 <0:参数错误
|
||||||
|
*****************************************************************/
|
||||||
|
int chrg_sink_volt_judge(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
|
||||||
|
{
|
||||||
|
rt_uint8_t stable_confirm_count;
|
||||||
|
static rt_uint8_t volt_low[TOTAL_SOU_CHS] = {0};
|
||||||
|
static rt_uint8_t no_curr[TOTAL_SOU_CHS] = {0};
|
||||||
|
static rt_uint8_t volt_set_ok[TOTAL_SOU_CHS] = {0};
|
||||||
|
static rt_uint8_t volt_stable_count[TOTAL_SOU_CHS] = {0};
|
||||||
|
static rt_tick_t running_start_tick[TOTAL_SOU_CHS] = {0};
|
||||||
|
|
||||||
|
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
stable_confirm_count = chrg_sink_voltage_confirm_count(
|
||||||
|
pSW->sink.pro_loadv);
|
||||||
|
|
||||||
|
if ((pSW->sink.On_work == 1) && (pSW->sink.test.test_mode == 0)) {
|
||||||
|
if (pSW->Now_voltage <= WORK_MIN_VOLT) {
|
||||||
|
volt_stable_count[idx] = 0;
|
||||||
|
if (volt_set_ok[idx] == 1 && ++volt_low[idx] >= 50) {
|
||||||
|
volt_set_ok[idx] = 0;
|
||||||
|
no_curr[idx] = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
volt_low[idx] = 0;
|
||||||
|
volt_set_ok[idx] = 1;
|
||||||
|
pSW->change_flag = 0;
|
||||||
|
if (pSW->sink.work_mode == SINK_WORK_LOW_MONITOR) {
|
||||||
|
/* 副继电器恢复后首次重新检测到输入电压,只启动协议重握手。 */
|
||||||
|
volt_stable_count[idx] = 0;
|
||||||
|
no_curr[idx] = 0;
|
||||||
|
pSW->sink.work_mode = SINK_WORK_WAIT;
|
||||||
|
} else if ((pSW->sink.work_mode == SINK_WORK_LOW) ||
|
||||||
|
(pSW->sink.work_mode == SINK_WORK_LOW_AUX_WAIT)) {
|
||||||
|
/* 掉电安全批次完成前,不得进入RUNING。 */
|
||||||
|
volt_stable_count[idx] = 0;
|
||||||
|
no_curr[idx] = 0;
|
||||||
|
} else if (pSW->Now_voltage > pSW->sink.volt_on) {
|
||||||
|
if ((pSW->sink.work_mode != SINK_WORK_RUNING) &&
|
||||||
|
(pSW->sink.work_mode != SINK_WORK_LOAD_STANDBY)) {
|
||||||
|
if (volt_stable_count[idx] < stable_confirm_count) {
|
||||||
|
volt_stable_count[idx]++;
|
||||||
|
}
|
||||||
|
if (volt_stable_count[idx] >= stable_confirm_count) {
|
||||||
|
/* 连续达到当前目标对应的确认帧数后进入RUNING。 */
|
||||||
|
volt_stable_count[idx] = 0;
|
||||||
|
pSW->sink.work_mode = SINK_WORK_RUNING;
|
||||||
|
running_start_tick[idx] = rt_tick_get();
|
||||||
|
no_curr[idx] = 0;
|
||||||
|
}
|
||||||
|
} else if (pSW->sink.work_mode == SINK_WORK_LOAD_STANDBY) {
|
||||||
|
volt_stable_count[idx] = 0;
|
||||||
|
no_curr[idx] = 0;
|
||||||
|
} else if ((pSW->Now_current > 200) || (pSW->sink.loadc < 200)) {
|
||||||
|
volt_stable_count[idx] = 0;
|
||||||
|
no_curr[idx] = 0;
|
||||||
|
} else if ((rt_tick_t)(rt_tick_get() - running_start_tick[idx]) >=
|
||||||
|
rt_tick_from_millisecond(SINK_CURRENT_START_GRACE_MS)) {
|
||||||
|
volt_stable_count[idx] = 0;
|
||||||
|
if (++no_curr[idx] >= 2) {
|
||||||
|
pSW->sink.work_mode = SINK_WORK_WAIT;
|
||||||
|
no_curr[idx] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
volt_stable_count[idx] = 0;
|
||||||
|
no_curr[idx] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
volt_low[idx] = 0;
|
||||||
|
no_curr[idx] = 0;
|
||||||
|
volt_set_ok[idx] = 0;
|
||||||
|
volt_stable_count[idx] = 0;
|
||||||
|
}
|
||||||
|
return chrg_sink_work(idx, pSW);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************
|
/*****************************************************************
|
||||||
@@ -877,8 +1009,12 @@ int chrg_sink_work(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
|
|||||||
}
|
}
|
||||||
work_mode = pSW->sink.work_mode;
|
work_mode = pSW->sink.work_mode;
|
||||||
workmode = work_mode;
|
workmode = work_mode;
|
||||||
|
if (work_mode != SINK_WORK_ON_TEST_SHORT) {
|
||||||
|
g_sink_short_start_tick[idx] = 0;
|
||||||
|
}
|
||||||
/* 异步等待状态需要持续检查批次或新量测,其余相同状态保持去重。 */
|
/* 异步等待状态需要持续检查批次或新量测,其余相同状态保持去重。 */
|
||||||
if ((work_mode == last_state[idx]) &&
|
if ((work_mode == last_state[idx]) &&
|
||||||
|
(work_mode != SINK_WORK_ON_TEST_SHORT) &&
|
||||||
(work_mode != SINK_WORK_INIT_AUX_WAIT) &&
|
(work_mode != SINK_WORK_INIT_AUX_WAIT) &&
|
||||||
(work_mode != SINK_WORK_STOP_WAIT) &&
|
(work_mode != SINK_WORK_STOP_WAIT) &&
|
||||||
(work_mode != SINK_WORK_STOP_RELAY_WAIT) &&
|
(work_mode != SINK_WORK_STOP_RELAY_WAIT) &&
|
||||||
@@ -904,7 +1040,11 @@ int chrg_sink_work(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
|
|||||||
ret = chrg_sink_TEST_DYNA_ON(idx,pSW);
|
ret = chrg_sink_TEST_DYNA_ON(idx,pSW);
|
||||||
break;
|
break;
|
||||||
case SINK_WORK_ON_TEST_SHORT:
|
case SINK_WORK_ON_TEST_SHORT:
|
||||||
ret = chrg_sink_TEST_SHORT_ON(idx,pSW);
|
if (work_mode != last_state[idx]) {
|
||||||
|
ret = chrg_sink_TEST_SHORT_ON(idx, pSW);
|
||||||
|
} else {
|
||||||
|
ret = chrg_sink_TEST_SHORT_KEEPALIVE(idx);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SINK_WORK_ON_TEST_OCP:
|
case SINK_WORK_ON_TEST_OCP:
|
||||||
ret = chrg_sink_TEST_OCP_ON(idx,pSW);
|
ret = chrg_sink_TEST_OCP_ON(idx,pSW);
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ struct chrg_switch_t;
|
|||||||
#define SINK_TEST_SHORT 1
|
#define SINK_TEST_SHORT 1
|
||||||
#define SINK_TEST_OCP 2
|
#define SINK_TEST_OCP 2
|
||||||
#define SINK_TEST_DYNA 3
|
#define SINK_TEST_DYNA 3
|
||||||
|
/* 短路测试期间按该周期补发WORK_START,防止功率板因超时停止。 */
|
||||||
|
#define SINK_SHORT_START_INTERVAL_MS 30U
|
||||||
//短路测试结构体
|
//短路测试结构体
|
||||||
struct test_short {
|
struct test_short {
|
||||||
rt_uint16_t hold_time; // 短路测试时间
|
rt_uint16_t hold_time; // 短路测试时间
|
||||||
@@ -208,6 +210,12 @@ enum {
|
|||||||
*/
|
*/
|
||||||
#define SINK_LOAD_ENABLE_MIN_MA 100U
|
#define SINK_LOAD_ENABLE_MIN_MA 100U
|
||||||
|
|
||||||
|
/* Sink电压稳定确认参数,供chrg_sink_volt_judge使用。 */
|
||||||
|
#define SINK_VOLT_5V_TARGET_MV 5000U
|
||||||
|
#define SINK_VOLT_CONFIRM_NORMAL_COUNT 5U
|
||||||
|
#define SINK_VOLT_CONFIRM_5V_COUNT 15U
|
||||||
|
#define SINK_CURRENT_START_GRACE_MS 200U
|
||||||
|
|
||||||
/* 主继电器闭合后的0V持续监控:由北向轮询线程每轮调用,掉电立即转掉电保护。 */
|
/* 主继电器闭合后的0V持续监控:由北向轮询线程每轮调用,掉电立即转掉电保护。 */
|
||||||
extern int chrg_sink_volt_low_protect(eIDX_SOU_CH idx, struct chrg_switch_t *pSW);
|
extern int chrg_sink_volt_low_protect(eIDX_SOU_CH idx, struct chrg_switch_t *pSW);
|
||||||
|
|
||||||
@@ -409,6 +417,7 @@ extern void chrg_nor_sink_test_run(rt_uint8_t ch, struct chrg_switch_t *pSW);
|
|||||||
/* 判断普通负载的当前设定是否允许启动电子负载。 */
|
/* 判断普通负载的当前设定是否允许启动电子负载。 */
|
||||||
extern rt_bool_t chrg_sink_load_should_start(const struct chrg_switch_t *pSW);
|
extern rt_bool_t chrg_sink_load_should_start(const struct chrg_switch_t *pSW);
|
||||||
extern int chrg_sink_work(eIDX_SOU_CH idx, struct chrg_switch_t *pSW);
|
extern int chrg_sink_work(eIDX_SOU_CH idx, struct chrg_switch_t *pSW);
|
||||||
|
extern int chrg_sink_volt_judge(eIDX_SOU_CH idx, struct chrg_switch_t *pSW);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+921
-2487
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
+2519
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,24 @@
|
|||||||
|
(ExpressProject ""
|
||||||
|
(ProjectVersion "19981106")
|
||||||
|
(Folder "Design Resources"
|
||||||
|
(Folder "Library")
|
||||||
|
(File ".\hc_dfcd_protocol.dsn"
|
||||||
|
(Type "Schematic Design"))
|
||||||
|
(BuildFileAddedOrDeleted "x")
|
||||||
|
(CompileFileAddedOrDeleted "x")
|
||||||
|
(NoModify))
|
||||||
|
(Folder "Outputs")
|
||||||
|
(Folder "Referenced Projects")
|
||||||
|
(PartMRUSelector)
|
||||||
|
(GlobalState
|
||||||
|
(FileView
|
||||||
|
(Path "Design Resources")
|
||||||
|
(Path "Design Resources" ".\hc_dfcd_protocol.dsn")
|
||||||
|
(Path "Design Resources" ".\hc_dfcd_protocol.dsn" "SCHEMATIC1")
|
||||||
|
(Select "Design Resources" ".\hc_dfcd_protocol.dsn" "SCHEMATIC1" "01_MCU"))
|
||||||
|
(HierarchyView)
|
||||||
|
(Doc
|
||||||
|
(Type "COrCapturePMDoc")
|
||||||
|
(Frame
|
||||||
|
(Placement "44 2 3 -1 -1 -8 -31 0 200 0 150"))
|
||||||
|
(Tab 0))))
|
||||||
Reference in New Issue
Block a user