diff --git a/apps/boot/application/main.c b/apps/boot/application/main.c index 8c11db6..7c48401 100644 --- a/apps/boot/application/main.c +++ b/apps/boot/application/main.c @@ -166,6 +166,56 @@ void MX_USART_DeInit (void) HAL_UART_DeInit(&huart2); } +static void boot_JumpToAPP (void) +{ + static uint32_t _stack_addr; /* APP ջ¶¥µØַ */ + static uint32_t _reset_handler; /* APP reset handler µØַ */ + typedef void(*APP_MAIN_FUNC)(void); + APP_MAIN_FUNC APP_Main; + + _stack_addr = *(volatile uint32_t *)BASE_APPLICATION; + _reset_handler = *(volatile uint32_t *)(BASE_APPLICATION + 4); + + /* ÉèÖÃËùÓÐʱÖӵ½ĬÈÏ״̬£¬ʹÓÃHSIʱÖÓ */ + HAL_RCC_DeInit(); + + /* ¹رÕȫ¾ÖÖжÏ */ + __disable_irq(); + + /* ¹رյδð¶¨ʱÆ÷£¬¸´λµ½ĬÈÏֵ */ + SysTick->CTRL = 0; + SysTick->LOAD = 0; + SysTick->VAL = 0; + + /* ¹رÕËùÓÐÖжϣ¬Çå³ýËùÓÐÖжϹÒÆð±ê־ */ + for (uint8_t i = 0; i < 8; i++) { + NVIC->ICER[i] = 0xFFFFFFFF; + NVIC->ICPR[i] = 0xFFFFFFFF; + } + + /* ÍâÉè deinit */ + HAL_DeInit(); + MX_USART_DeInit(); + MX_DMA_DeInit(); + + + /* ÉèÖÃÖ÷¶ÑջָÕë */ + __set_MSP(_stack_addr); + + /* ÔÚ RTOS ¹¤³̣¬ÕâÌõÓï¾äºÜÖØҪ£¬ÉèÖÃΪÌØȨ¼¶ģʽ£¬ʹÓà MSP ָÕë */ + __set_CONTROL(0); + + /* ÉèÖÃÖжÏÏòÁ¿±í */ + SCB->VTOR = BASE_APPLICATION; + + /* Ìøתµ½ APP £¬Ê׵ØַÊÇ MSP £¬µØַ +4 ÊǸ´λÖжϷþÎñ³ÌÐòµØַ */ + APP_Main = (APP_MAIN_FUNC)_reset_handler; + APP_Main(); + + /* ¸´λ»òÌøת³ɹ¦µĻ°£¬²»»áִÐе½ÕâÀï */ + while (1) { + } +} int main (void) { @@ -190,9 +240,10 @@ int main (void) VERSION_MAIN, VERSION_SUB, VERSION_FIX, BUILD_TIMESTAMP); #endif APP_Init(); - + boot_JumpToAPP(); while (1) { - APP_Running(); + + //APP_Running(); } return -1; diff --git a/apps/chrg/applications/bsp/chrg_gpio.h b/apps/chrg/applications/bsp/chrg_gpio.h index 624ca38..96bfce7 100644 --- a/apps/chrg/applications/bsp/chrg_gpio.h +++ b/apps/chrg/applications/bsp/chrg_gpio.h @@ -32,18 +32,18 @@ #define GPO_PIN_CH1_P2 GET_PIN(C, 1) // P2 connect K5 for GND/PGND // 北向继电器2组 -#define GPO_PIN_CH2_P0 GET_PIN(A, 5) // P0 -#define GPO_PIN_CH2_P1 GET_PIN(A, 4) // P1 +#define GPO_PIN_CH2_P0 GET_PIN(A, 5) // P0 //SINK D+D- CC +#define GPO_PIN_CH2_P1 GET_PIN(A, 4) // P1 //SOURCE D+D- CC #define GPO_PIN_CH2_P2 GET_PIN(A, 1) // P2 // 北向继电器3组 -#define GPO_PIN_CH3_P0 GET_PIN(C, 5) // P0 -#define GPO_PIN_CH3_P1 GET_PIN(C, 4) // P1 +#define GPO_PIN_CH3_P0 GET_PIN(C, 5) // P0 //SINK D+D- CC +#define GPO_PIN_CH3_P1 GET_PIN(C, 4) // P1 //SOURCE D+D- CC #define GPO_PIN_CH3_P2 GET_PIN(A, 7) // P2 // 北向继电器4组 -#define GPO_PIN_CH4_P0 GET_PIN(B, 15) // P0 -#define GPO_PIN_CH4_P1 GET_PIN(B, 14) // P1 +#define GPO_PIN_CH4_P0 GET_PIN(B, 15) // P0 //SINK D+D- CC +#define GPO_PIN_CH4_P1 GET_PIN(B, 14) // P1 //SOURCE D+D- CC #define GPO_PIN_CH4_P2 GET_PIN(B, 13) // P2 // 北向通信口选通 U14 diff --git a/apps/chrg/applications/thread/chrg_comm.c b/apps/chrg/applications/thread/chrg_comm.c index 9258747..4cb1a8f 100644 --- a/apps/chrg/applications/thread/chrg_comm.c +++ b/apps/chrg/applications/thread/chrg_comm.c @@ -2563,6 +2563,7 @@ static eMBException chrg_comm_apply_source_effect(rt_uint8_t ch, rt_bool_t protocol_switch_requested; rt_bool_t need_source_reset; rt_uint8_t new_pd_state; + rt_uint8_t old_pd_state; struct vc_pd_t old_pd_set; eSRC_PRO old_protocol = pReal->source.protocol; rt_uint8_t old_cc_set = pReal->source.CC_Set; @@ -2589,8 +2590,10 @@ static eMBException chrg_comm_apply_source_effect(rt_uint8_t ch, protocol_switch_requested = north_config_changed; new_pd_state = chrg_comm_source_pd_state( (rt_uint8_t)pShadow->source.protocol); - need_source_reset = (last_pd_pro[ch] != SOURCE_PD_STATE_UNKNOWN) && - (last_pd_pro[ch] != new_pd_state); + /* 只有已知的非PD -> PD切换执行完整硬件复位。 */ + old_pd_state = chrg_comm_source_pd_state((rt_uint8_t)old_protocol); + need_source_reset = (old_pd_state == SOURCE_PD_STATE_NON_PD) && + (new_pd_state == SOURCE_PD_STATE_PD); target_curr = pShadow->source.pd_set.mm.max_cur; /* 影子区只拥有COM配置;北向解析产生的运行目标和回读数据继续由pReal持有。 */ @@ -2637,7 +2640,8 @@ static eMBException chrg_comm_apply_source_effect(rt_uint8_t ch, * sub已在上方确定,北向轮询线程执行本状态并清零成功后,继续 * CC_CLOSE或协议设置,不需要COM直接发送任何清零命令。 */ - pReal->source.work_mode = SOURCE_WORK_PROTOCOL_SWITCH; + pReal->source.work_mode = need_source_reset ? + SOURCE_WORK_FULL_RESET : SOURCE_WORK_PROTOCOL_SWITCH; } if (pReal->source.protocol != PRO_NONE) { diff --git a/apps/chrg/applications/thread/chrg_north.h b/apps/chrg/applications/thread/chrg_north.h index 532c1aa..8ad285d 100644 --- a/apps/chrg/applications/thread/chrg_north.h +++ b/apps/chrg/applications/thread/chrg_north.h @@ -22,8 +22,8 @@ #define LEN_FRAME_HEAD (4) // [帧长, 0x00, id, 命令] #define MIN_FRAME_LENGTH (5) // 帧最短5字节 #define WORK_MIN_VOLT 3000 // 工作电压下限,单位mV -#define NORTH_FRAME_DEBUG 0x01 // 北向UART原始收发帧 -#define NORTH_SOURCE_DEBUG 0x00 // Source协议解析及组帧 +#define NORTH_FRAME_DEBUG 0x00 // 北向UART原始收发帧 +#define NORTH_SOURCE_DEBUG 0x01 // Source协议解析及组帧 #define NORTH_SINK_DEBUG 0x00 // Sink协议解析及组帧 #define SOUTH_FRAME_DEBUG 0x00 // 南向UART原始收发帧 #define SOUTH_COMMAND_DEBUG 0x01 // 南向寄存器写命令 diff --git a/apps/chrg/applications/thread/chrg_roll_nor.c b/apps/chrg/applications/thread/chrg_roll_nor.c index 70af2da..b944c52 100644 --- a/apps/chrg/applications/thread/chrg_roll_nor.c +++ b/apps/chrg/applications/thread/chrg_roll_nor.c @@ -157,6 +157,10 @@ static rt_bool_t chrg_roll_nor_source_wait_process(rt_uint8_t ch, chrg_roll_nor_source_switch_reset(ch); return RT_FALSE; } + if (pSW->source.work_mode == SOURCE_WORK_INIT_WAIT) { + /* 南向初始化批次未完成时,禁止发送北向协议命令。 */ + return RT_TRUE; + } if (pSW->sub == IDX_WAIT_SOURCE_PROTOCOL) { if ((g_source_protocol_wait_mask & bit) == 0U) { @@ -795,6 +799,7 @@ static int chrg_roll_nor_auto_request(rt_uint8_t idx, struct chrg_switch_t *pSW, struct chrg_thread_t *pTHR, struct chrg_thread_t *pTN, struct chrg_north_t *pNOR) { + rt_bool_t advance_sub = RT_TRUE; rt_uint8_t attempt; // 当前发送序号:0为首次,1~2为重发 rt_uint8_t request_sub = 0; // 本次请求实际使用的sub快照 rt_uint8_t next_sub = 0; // 正确回码后准备提交的候选sub @@ -868,7 +873,10 @@ static int chrg_roll_nor_auto_request(rt_uint8_t idx, /* ID、命令、CRC和配置版本均确认有效后,才正式推进实时sub。 */ if ((expected_id == ID_SOURCE) && (request_sub == IDX_SET_SOURCE_RESET)) { - /* 参与通道全部收到0x17=3应答后,共享一次300ms保护等待。 */ + /* 复位回码后重新执行Source INIT,初始化完成后再推进到PD。 */ + pSW->source.work_mode = SOURCE_WORK_INIT; + advance_sub = RT_FALSE; + /* INIT完成前保持当前sub,禁止通用逻辑提前推进到PD。 */ } else if ((expected_id == ID_SOURCE) && (request_sub == IDX_SET_SOURCE_PD)) { /* 0xD0应答后每通道独立等待100ms,再连接目标CC。 */ @@ -887,7 +895,7 @@ static int chrg_roll_nor_auto_request(rt_uint8_t idx, } /* 业务解析可能主动切换sub,例如掉电恢复后要求重新设置协议。 * 只有sub仍属于本次请求时,才应用请求函数计算出的next_sub。 */ - if (pSW->sub == request_sub) { + if (advance_sub && (pSW->sub == request_sub)) { pSW->sub = next_sub; } rt_mutex_release(pTHR->mutex); @@ -960,7 +968,12 @@ void chrg_roll_nor_thread_entry (void *data) if ((pSW->id == ID_SOURCE) && ((pSW->source.work_mode == SOURCE_WORK_INIT) || (pSW->source.work_mode == SOURCE_WORK_STOP) || - (pSW->source.work_mode == SOURCE_WORK_PROTOCOL_SWITCH))) { + (pSW->source.work_mode == SOURCE_WORK_PROTOCOL_SWITCH) || + (pSW->source.work_mode == SOURCE_WORK_FULL_RESET) || + (pSW->source.work_mode == SOURCE_WORK_FULL_RESET_WAIT) || + (pSW->source.work_mode == SOURCE_WORK_FULL_RESET_RELAY) || + (pSW->source.work_mode == SOURCE_WORK_FULL_RESET_RELAY_WAIT) || + (pSW->source.work_mode == SOURCE_WORK_INIT_WAIT))) { state_work_ret = chrg_source_work_state(idx, pSW); } else if ((pSW->id == ID_SINK) && ((pSW->sink.work_mode == SINK_WORK_INIT) || diff --git a/apps/chrg/applications/thread/chrg_roll_sou.c b/apps/chrg/applications/thread/chrg_roll_sou.c index ad9d2a8..0643b9f 100644 --- a/apps/chrg/applications/thread/chrg_roll_sou.c +++ b/apps/chrg/applications/thread/chrg_roll_sou.c @@ -35,6 +35,11 @@ chrg_rollsou_com_t g_sou_com_batch = {0}; static rt_uint8_t g_sou_measure_once_pending_mask = 0U; static rt_uint8_t g_sou_measure_once_active_mask = 0U; +/* A channel enters normal measurement polling only after its version probe + * receives a valid response. A failed probe remains pending for the next + * round, which also covers the south board's slower power-up time. */ +static rt_uint8_t g_sou_version_ready[TOTAL_SOU_CHS] = {0U}; + /* COM批量命令按通道轮询发送。一次写命令收到匹配回码后才移动游标; * 回码错误或超时时游标保持不变,使同一条命令优先完成重发,避免破坏 * 本通道批次内的寄存器执行顺序。 */ @@ -770,6 +775,7 @@ void chrg_roll_sou_thread_entry (void *data) rt_uint16_t single_value = 0; rt_bool_t command_valid = RT_FALSE; rt_bool_t measure_once = RT_FALSE; + rt_bool_t version_probe = RT_FALSE; rt_uint8_t response_part = MB_R_PART1; rt_err_t ret = RT_EOK; struct chrg_rollsou_t *pROLL = &chrgrollsou; @@ -785,6 +791,7 @@ void chrg_roll_sou_thread_entry (void *data) rt_mutex_release(pTHR->mutex); command_valid = RT_FALSE; measure_once = RT_FALSE; + version_probe = RT_FALSE; response_part = MB_R_PART1; if ((run != RUN_COM) && (run != RUN_UPDATA)) { retry_count = 0; @@ -802,7 +809,12 @@ void chrg_roll_sou_thread_entry (void *data) pROLL->idx = (eIDX_SOU_CH)idx; chrg_south_switch((eIDX_SOU_CH)idx); } - chrg_eload_refresh(ID_ELOAD, MB_R_PART1); + if (g_sou_version_ready[idx] == 0U) { + version_probe = RT_TRUE; + chrg_eload_read_version(ID_ELOAD); + } else { + chrg_eload_refresh(ID_ELOAD, MB_R_PART1); + } break; } idx = index%(TOTAL_SOU_CHS); // [0, 3] @@ -818,7 +830,12 @@ void chrg_roll_sou_thread_entry (void *data) chrg_south_switch((eIDX_SOU_CH)idx); pROLL->part = MB_R_PART1; } - chrg_eload_refresh(ID_ELOAD, pROLL->part); + if (g_sou_version_ready[idx] == 0U) { + version_probe = RT_TRUE; + chrg_eload_read_version(ID_ELOAD); + } else { + chrg_eload_refresh(ID_ELOAD, pROLL->part); + } if (pROLL->part < TOTAL_MB_R) { index++; } @@ -843,6 +860,7 @@ void chrg_roll_sou_thread_entry (void *data) batch_ch = command_ch; command_valid = RT_TRUE; chrg_south_switch((eIDX_SOU_CH)command_ch); + rt_kprintf("ch=%d",command_ch); chrg_eload_write_reg(ID_ELOAD, command_reg, command_value); } break; @@ -907,7 +925,16 @@ void chrg_roll_sou_thread_entry (void *data) } else if (run != RUN_AUTO) { sou_single_command_finish(run); } else { - chrg_eload_parse(idx, response_part, pMB_R->payload, pMB_R->length); + if (version_probe) { + if (chrg_eload_parse_version(idx, pMB_R->payload, + pMB_R->length) == 0) { + g_sou_version_ready[idx] = 1U; + pROLL->part = MB_R_PART1; + } + } else { + chrg_eload_parse(idx, response_part, pMB_R->payload, + pMB_R->length); + } } } else if (run == RUN_COM) { sou_com_command_failed(batch_ch, command_reg, command_value, diff --git a/apps/chrg/applications/utils/chrg_eload.c b/apps/chrg/applications/utils/chrg_eload.c index 2356154..2826834 100644 --- a/apps/chrg/applications/utils/chrg_eload.c +++ b/apps/chrg/applications/utils/chrg_eload.c @@ -179,6 +179,14 @@ int chrg_eload_read_regs (rt_uint8_t addr, rt_uint16_t reg, rt_uint16_t len) return chrg_south_send(buf, 8); } +/* Read the version first so a newly powered south board is not queried with + * the long measurement frame before its Modbus interface is ready. */ +int chrg_eload_read_version (rt_uint8_t addr) +{ + return chrg_eload_read_regs(addr, MODBUSRTU_SW_VERSION_REG, + MODBUSRTU_SW_VERSION_LEN); +} + /***************************************************************** 函数名称: chrg_eload_send_ymodem_data 函数描述: 向南向发送ymodem协议升级数据 @@ -292,6 +300,24 @@ int chrg_eload_refresh (rt_uint8_t addr, rt_uint8_t part) return ret; } +int chrg_eload_parse_version (rt_uint8_t idx, rt_uint8_t *data, rt_uint16_t len) +{ + rt_uint16_t version; + + /* A one-register Modbus 0x03 response is 7 bytes including CRC16. */ + if ((idx >= TOTAL_SOU_CHS) || (data == RT_NULL) || + (len != (MODBUSRTU_SW_VERSION_LEN * 2U + 5U)) || + (data[0] != ID_ELOAD) || (data[1] != MB_REGISTER_RD) || + (data[2] != 2U) || (mb_crc16(data, len) != 0U)) { + return -1; + } + + version = u8v_to_u16(&data[3]); + /* HOLD_REG_CH0_VERSION is the per-channel south board version register. */ + usRegHoldBuf[HOLD_REG_CH0_VERSION + idx * TOTAL_HOLD_CH_REGS] = version; + return 0; +} + /***************************************************************** 函数名称: chrg_eload_parse 函数描述: 解析源载返回数据 diff --git a/apps/chrg/applications/utils/chrg_eload.h b/apps/chrg/applications/utils/chrg_eload.h index 10b92e0..0fbd63a 100644 --- a/apps/chrg/applications/utils/chrg_eload.h +++ b/apps/chrg/applications/utils/chrg_eload.h @@ -164,6 +164,10 @@ typedef enum { TOTAL_MB_R } eIDX_MB_PART; +/* South board firmware version register: one 16-bit register at 0x0301. */ +#define MODBUSRTU_SW_VERSION_REG 0x0301U +#define MODBUSRTU_SW_VERSION_LEN 1U + #define SIZE_P1_RD 19 // 读19个寄存器 #define SIZE_P2_RD 28 // 读28个寄存器 @@ -239,6 +243,15 @@ struct chrg_eload_t { *****************************************************************/ extern int chrg_eload_read_regs (rt_uint8_t addr, rt_uint16_t reg, rt_uint16_t len); +/***************************************************************** +Function: chrg_eload_read_version +Description: Request the south board firmware version register. +Input: addr: south board address +Output: - +Return: <0: error, >0: sent length +*****************************************************************/ +extern int chrg_eload_read_version (rt_uint8_t addr); + /***************************************************************** 函数名称: chrg_eload_write_reg 函数描述: 向南向发送写单个寄存器 @@ -268,6 +281,15 @@ extern int chrg_eload_refresh (rt_uint8_t addr, rt_uint8_t part); 其它说明: - *****************************************************************/ extern int chrg_eload_parse (rt_uint8_t idx, rt_uint8_t pt, rt_uint8_t *data, rt_uint16_t len); + +/***************************************************************** +Function: chrg_eload_parse_version +Description: Parse and store a valid south board firmware version. +Input: idx: channel, data: Modbus response, len: response length +Output: firmware version is stored at the channel version register +Return: 0: valid, <0: invalid response +*****************************************************************/ +extern int chrg_eload_parse_version (rt_uint8_t idx, rt_uint8_t *data, rt_uint16_t len); /***************************************************************** 函数名称: chrg_eload_get_sample_seq 函数描述: 获取指定南向通道P1量测数据的更新序号 diff --git a/apps/chrg/applications/utils/chrg_source.c b/apps/chrg/applications/utils/chrg_source.c index b38d3ed..f50d3a7 100644 --- a/apps/chrg/applications/utils/chrg_source.c +++ b/apps/chrg/applications/utils/chrg_source.c @@ -21,6 +21,16 @@ static int chrg_source_work_running(eIDX_SOU_CH idx, struct chrg_switch_t *pSW); +static int chrg_source_work_full_reset(eIDX_SOU_CH idx, + struct chrg_switch_t *pSW); +static int chrg_source_work_full_reset_wait(eIDX_SOU_CH idx, + struct chrg_switch_t *pSW); +static int chrg_source_work_full_reset_relay(eIDX_SOU_CH idx, + struct chrg_switch_t *pSW); +static int chrg_source_work_full_reset_relay_wait(eIDX_SOU_CH idx, + struct chrg_switch_t *pSW); +static int chrg_source_work_init_wait(eIDX_SOU_CH idx, + struct chrg_switch_t *pSW); /***************************************************************** 函数名称: chrg_source_init_submit @@ -39,7 +49,7 @@ int chrg_source_init_submit(rt_uint8_t idx, struct chrg_switch_t *pSW) rt_uint16_t regs[5] = { REG_ELOAD, REG_MODE, - 0x01, + REG_REL_ON, REG_CURRENT_OUT + 1, REG_WORK }; @@ -88,8 +98,38 @@ static int chrg_source_work_init(eIDX_SOU_CH idx, struct chrg_switch_t *pSW) pNOR->enable[idx] = 1; pSOU->online[idx] = 1; chrg_nor_sw_rel((eIDX_NOR_CH)idx, ID_SOURCE); + /* 初始化批次必须全部收到南向回码后,才能继续协议设置或输出控制。 */ + pSW->source.work_mode = SOURCE_WORK_INIT_WAIT; + return 0; +} + +static int chrg_source_work_init_wait(eIDX_SOU_CH idx, + struct chrg_switch_t *pSW) +{ + int result; + + if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) { + return -1; + } + if (chrg_sou_com_batch_is_pending(idx)) { + return 1; + } + result = chrg_sou_com_batch_get_result(idx); + if (result <= 0) { + /* 南向初始化失败时,保持北向协议不变并重发完整初始化批次。 */ + pSW->source.work_mode = SOURCE_WORK_INIT; + return 1; + } + + if (pSW->sub == IDX_SET_SOURCE_RESET) { + /* 复位后的初始化完成,才允许进入PD协议设置。 */ + pSW->sub = IDX_SET_SOURCE_PD; + pSW->source.work_mode = SOURCE_WORK_WAIT; + return 0; + } + if (pSW->source.protocol == PRO_NONE) { - /* 标准协议没有协商回码,INIT成功后立即由RUNING统一写入电压。 */ + /* 标准协议不等待协商,初始化完成后直接写入目标电压。 */ pSW->source.work_mode = SOURCE_WORK_RUNING; return chrg_source_work_running(idx, pSW); } @@ -173,6 +213,87 @@ static int chrg_source_work_protocol_switch(eIDX_SOU_CH idx, return 0; } +static int chrg_source_work_full_reset(eIDX_SOU_CH idx, + struct chrg_switch_t *pSW) +{ + rt_uint16_t reg = REG_WORK; + rt_uint16_t value = WORK_STOP; + + /* Cancel stale south commands so the reset sequence starts from a known state. */ + if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) { + return -1; + } + if (chrg_sou_com_batch_cancel(idx) != 0) { + return -1; + } + if (chrg_sou_com_batch_submit(idx, ®, &value, 1) != 0) { + return -1; + } + pSW->source.set_volt = 0; + pSW->source.work_mode = SOURCE_WORK_FULL_RESET_WAIT; + return 1; +} + +static int chrg_source_work_full_reset_wait(eIDX_SOU_CH idx, + struct chrg_switch_t *pSW) +{ + int result; + + if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) { + return -1; + } + if (chrg_sou_com_batch_is_pending(idx)) { + return 1; + } + result = chrg_sou_com_batch_get_result(idx); + if (result <= 0) { + pSW->source.work_mode = SOURCE_WORK_FULL_RESET; + return 1; + } + pSW->source.work_mode = SOURCE_WORK_FULL_RESET_RELAY; + return 1; +} + +static int chrg_source_work_full_reset_relay(eIDX_SOU_CH idx, + struct chrg_switch_t *pSW) +{ + rt_uint16_t reg = REG_REL_ON; + rt_uint16_t value = ALL_REL_OFF; + + if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) { + return -1; + } + if (chrg_sou_com_batch_submit(idx, ®, &value, 1) != 0) { + return -1; + } + pSW->source.work_mode = SOURCE_WORK_FULL_RESET_RELAY_WAIT; + return 1; +} + +static int chrg_source_work_full_reset_relay_wait(eIDX_SOU_CH idx, + struct chrg_switch_t *pSW) +{ + int result; + + if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) { + return -1; + } + if (chrg_sou_com_batch_is_pending(idx)) { + return 1; + } + result = chrg_sou_com_batch_get_result(idx); + if (result <= 0) { + pSW->source.work_mode = SOURCE_WORK_FULL_RESET_RELAY; + return 1; + } + + /* South relays are off; now disconnect D+/D- and CC before SOURCE_RESET. */ + chrg_nor_sw_rel((eIDX_NOR_CH)idx, 0); + pSW->sub = IDX_SET_SOURCE_RESET; + pSW->source.work_mode = SOURCE_WORK_WAIT; + return 1; +} + /***************************************************************** 函数名称: chrg_source_work_stop 函数描述: 执行电源主动关机流程 @@ -266,6 +387,16 @@ int chrg_source_work_state(rt_uint8_t idx, struct chrg_switch_t *pSW) return chrg_source_work_switch(idx, pSW); case SOURCE_WORK_PROTOCOL_SWITCH: return chrg_source_work_protocol_switch(idx, pSW); + case SOURCE_WORK_FULL_RESET: + return chrg_source_work_full_reset(idx, pSW); + case SOURCE_WORK_FULL_RESET_WAIT: + return chrg_source_work_full_reset_wait(idx, pSW); + case SOURCE_WORK_FULL_RESET_RELAY: + return chrg_source_work_full_reset_relay(idx, pSW); + case SOURCE_WORK_FULL_RESET_RELAY_WAIT: + return chrg_source_work_full_reset_relay_wait(idx, pSW); + case SOURCE_WORK_INIT_WAIT: + return chrg_source_work_init_wait(idx, pSW); default: return -1; } diff --git a/apps/chrg/applications/utils/chrg_source.h b/apps/chrg/applications/utils/chrg_source.h index df3ee28..75b6377 100644 --- a/apps/chrg/applications/utils/chrg_source.h +++ b/apps/chrg/applications/utils/chrg_source.h @@ -169,6 +169,11 @@ enum { SOURCE_WORK_STOP, // 主动停止并关闭通道 SOURCE_WORK_SWITCH, // 停止旧负载后进入电源INIT SOURCE_WORK_PROTOCOL_SWITCH, // 协议/CC切换前清零功率板输出 + SOURCE_WORK_FULL_RESET, // Submit output clear and stop commands + SOURCE_WORK_FULL_RESET_WAIT, // Wait for output clear and stop + SOURCE_WORK_FULL_RESET_RELAY, // Submit south relay-off command + SOURCE_WORK_FULL_RESET_RELAY_WAIT,// Wait before disconnecting north relay + SOURCE_WORK_INIT_WAIT, // Wait for Source init batch completion SOURCE_WORK_ON_TEST_DYNA, SOURCE_WORK_ON_TEST_SHORT, };