diff --git a/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/inc/config.h b/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/inc/config.h index f2d5762..c930c42 100644 --- a/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/inc/config.h +++ b/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/inc/config.h @@ -30,8 +30,18 @@ #define TYPEC_PORT_MAX 2 #define USER_DERAT_ENABLE 1 -#define USER_NTC_ENABLE 0 -#define SWITCH_LINE_OFF_PROTECTION 0 +#define USER_NTC_ENABLE 1 + +// 为了解决GT5手机, 重新广播src_cap时,这时候会反灌一下电压。 +// 比如广播src_cap,手机请求了5V,然而自身反灌电压,导致一直调压失败 +#define SWITCH_LINE_OFF_PROTECTION 1 + +// 解决华为matebook_x设备兼容性问题: 该设备识别到pdo有pps档会不停的复位。 +// 收到sofo_reset的时候开始倒计时3秒, 三秒内连续收到三次,则识别该设备为 matebook_x +// 拔出的时候, 把该标志清除。 +#define HUAWEI_MATEBOOK_X 1 + +#define PD_PACKAGE_CONFLICT_SOLVE 0 extern uint16_t system_1ms_cnt; extern uint16_t system_1s_cnt; @@ -57,7 +67,7 @@ extern uint16_t system_1s_cnt; #endif /******************log debug***************************/ -#define UART_DEUG 0 +#define UART_DEUG 0 #if UART_DEUG #define log_info comp_uart2_sync_print #else @@ -73,12 +83,12 @@ extern uint16_t system_1s_cnt; /****************project inforamtion MTP ADDR:0x100000C0*******************/ #define SOFT_WARE_VERISION_H 0x00 -#define SOFT_WARE_VERISION_L 0x06 +#define SOFT_WARE_VERISION_L 0x08 #define CUSTOM_ID 0xA1 #define PROJECT_ID 0x60 /**********************���칦�ܺ궨��************************************/ /*The voltage is adjusted to a percentage of ps rdy*/ -#define PERCENT_OF_VOL_REGULA 10//5 /*5--±5%*/ +#define PERCENT_OF_VOL_REGULA 5 /*5--±5%*/ /*Do not look at the voltage adjustment completed current difference */ #define PS_RDY_CHECK_CURRENT 250 /*Cable impedance SNS R*/ diff --git a/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/inc/customized.h b/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/inc/customized.h index 1f44cc5..8736b81 100644 --- a/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/inc/customized.h +++ b/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/inc/customized.h @@ -113,10 +113,22 @@ typedef struct bool c1_priority_inser; // C1口优先C2口接进来 = 1 代表是 bool need_switch_mos; - bool new_request_receive_done; // 新request接收完成 + bool wait_c2_switch_done; // 新request接收完成 - volatile uint16_t protection_off_2s; + volatile uint16_t protection_off_2s[2]; bool protection_off_flag[2]; + + bool protect_en; //保护是否使能 + +#if HUAWEI_MATEBOOK_X + uint16_t matebook_cnt_3s[2]; + uint16_t received_sofo_reset_cnt[2]; + bool equipment_is_matebook_x[2]; // 插入的设备是华为matebook x +#endif + + // typec状态机 + bool type_c1_connect; + bool type_c2_connect; } user_app_s; extern user_app_s user_app; @@ -341,6 +353,8 @@ void usba_detection(void); void insertion_equipment_judgment(void); void port_inser_priority_judgment(void); void gate3_control(bool enable); +void solve_huawei_matebook(uint8_t port, pd_param_s* pd_param); +void user_timer_event(uint8_t port); #if USER_NTC_ENABLE // void ntc_judgment(void); diff --git a/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/inc/port1_customized.h b/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/inc/port1_customized.h index 68b6c0f..dafd107 100644 --- a/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/inc/port1_customized.h +++ b/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/inc/port1_customized.h @@ -28,6 +28,7 @@ extern const uint8_t port1_scp_register_value[256]; extern const scp_def_vol_s PORT1_SCP_DEF_VOL[]; //scp power curve for 0xd0~0xdf. +void port1_scp_derate(bool en); /* * @brief port1_scp_register_attr_upgrade diff --git a/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/src/comp_dac.c b/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/src/comp_dac.c index 973ca65..0dc21d8 100644 --- a/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/src/comp_dac.c +++ b/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/src/comp_dac.c @@ -22,6 +22,8 @@ uint16_t req_cc[TYPEC_PORT_MAX] = {0, 0}; */ void comp_dac_close_vbus(uint8_t port) { + log_info("close_vbus:%d\n", port); + switch(port) { case TYPEC_PORT0: @@ -273,6 +275,8 @@ void port0_opto_cv(uint8_t port, uint16_t val) { uint32_t temp[TYPEC_PORT_MAX + 1] = {0}; + // log_info("set_val:%d\n", val); + temp[port] = CV0_LOOP_TRIM_COEFF(val); if(temp[port] >= DAC_CV01_BIT) @@ -306,11 +310,6 @@ static void comp_dac_cv_acdc(uint8_t port, uint16_t val) { uint32_t temp[TYPEC_PORT_MAX + 1] = {0}; - bool type_c1_state = 0, type_c2_state = 0; - - type_c1_state = (g_app_protocol_param[0].pd_param.typec_status.typec_status == AttachedSRC); - type_c2_state = (g_app_protocol_param[1].pd_param.typec_status.typec_status == AttachedSRC); - switch(port) { case TYPEC_PORT0: @@ -323,8 +322,9 @@ static void comp_dac_cv_acdc(uint8_t port, uint16_t val) else // port1 { // 单C2时, 是使用C1的ACDC来调压,不需要用到C2的 - if(!type_c1_state && type_c2_state) + if(!user_app.type_c1_connect && user_app.type_c2_connect) { + g_powerout_info[TYPEC_PORT0].set_vol = val; port0_opto_cv(TYPEC_PORT0, val); } @@ -450,16 +450,12 @@ static void comp_dac_cc_2dcdc_fb(uint8_t port, uint16_t val, uint16_t offset) #endif } -uint16_t test_current; static void comp_dac_cc_acdc(uint8_t port, uint16_t val, uint16_t offset) { uint32_t value[TYPEC_PORT_MAX] = {0}; int16_t temp[TYPEC_PORT_MAX] = {0}; - // log_info("opto_set_cc port:%d cc_val:%d\n", port, val); - - // 仅测试, C2口用第一路acdc, 走gate3时设置3.7A实际只能出3.3A - test_current = val; + //log_info("opto_set_cc port:%d cc_val:%d\n", port, val); if(port == TYPEC_PORT0) { @@ -510,12 +506,6 @@ static void comp_dac_cc_acdc(uint8_t port, uint16_t val, uint16_t offset) */ void comp_dac_cc_target_set(uint8_t port, uint16_t val, uint16_t offset) { - bool type_c1_state = 0, type_c2_state = 0; - - type_c1_state = (g_app_protocol_param[0].pd_param.typec_status.typec_status == AttachedSRC); - type_c2_state = (g_app_protocol_param[1].pd_param.typec_status.typec_status == AttachedSRC); - - if(port >= TYPEC_PORT_MAX) { return; @@ -530,12 +520,13 @@ void comp_dac_cc_target_set(uint8_t port, uint16_t val, uint16_t offset) // 单C2时, cc是opto调流。 // C1 + C2时, C1是opto调流, C2是FB调流 - if(type_c1_state && !type_c2_state) // 单C1 + if(user_app.type_c1_connect && !user_app.type_c2_connect) // 单C1 { comp_dac_cc_acdc(TYPEC_PORT0, val, offset); } - else if(!type_c1_state && type_c2_state) // 单C2 + else if(!user_app.type_c1_connect && user_app.type_c2_connect) // 单C2 { + g_powerout_info[TYPEC_PORT0].set_current = val; comp_dac_cc_acdc(TYPEC_PORT0, val, offset); comp_dac_cc_2dcdc_fb(TYPEC_PORT1, val, offset); // 另外一路的电流也设到一样的 } diff --git a/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/src/comp_protection.c b/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/src/comp_protection.c index 26b4f85..120d14e 100644 --- a/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/src/comp_protection.c +++ b/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/src/comp_protection.c @@ -271,8 +271,8 @@ void comp_protection_monitor(uint8_t port, protection_param_s *protection_param) // log_info("port:%d,%d,%d\n", port, pro_vpt[port][PROT_UVP], adc_sample[port][PROT_UVP]); // C1 + C2情况下, C2走5V时的OCP需要软件来做 - if(g_app_protocol_param[TYPEC_PORT0].pd_param.typec_status.typec_status == AttachedSRC - && g_app_protocol_param[TYPEC_PORT1].pd_param.typec_status.typec_status == AttachedSRC + if(user_app.type_c1_connect + && user_app.type_c2_connect && g_powerout_info[TYPEC_PORT1].set_vol <= VOLTAGE_5P5V) { adc_sample[TYPEC_PORT1][PROT_OCP] = comp_adc_get_cur12(TYPEC_PORT1); @@ -618,18 +618,6 @@ void comp_protection_run(uint8_t port) case PRO_MONITOR: if(!timer_cnt[port]) { - // 哪个口有接入,哪个口才开启保护 - // if( g_app_protocol_param[port].pd_param.typec_status.typec_status != AttachedSRC ) - // { - // g_protection_param.protection_param[0].protection_enable = PORT_OTP_ENABLE; - // g_protection_param.protection_param[1].protection_enable = PORT_OTP_ENABLE; - // } - // else - // { - // g_protection_param.protection_param[0].protection_enable |= VIN_UVP_ENABLE | DPDN_WET_ENABLE | PORT_OTP_ENABLE; - // g_protection_param.protection_param[1].protection_enable |= VIN_UVP_ENABLE | DPDN_WET_ENABLE | VIN_OVP_ENABLE | VIN_OCP_ENABLE | PORT_OTP_ENABLE; - // } - if(g_app_protocol_param[port].pd_param.typec_status.typec_status != AttachedSRC) { return; diff --git a/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/src/customized.c b/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/src/customized.c index cbc38bd..6dade09 100644 --- a/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/src/customized.c +++ b/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/src/customized.c @@ -434,6 +434,29 @@ void pd_src_cap_init(uint8_t port, pd_param_s*pd_param, uint8_t pwr_cnt) // } #endif +void user_timer_event(uint8_t port) +{ +#if HUAWEI_MATEBOOK_X + + if(user_app.matebook_cnt_3s[port]) + { + user_app.matebook_cnt_3s[port]--; + } + + // 识别完成后,需要主动断开一次,但是断开的话会把标志位给清了。 所以在倒计时3秒内断的话不清标志 + // if((g_app_protocol_param[port].pd_param.typec_status.typec_status == UnattachedSRC) + // && (user_app.matebook_cnt_3s[port] == 0)) + if(g_app_protocol_param[port].pd_param.typec_status.typec_status == UnattachedSRC) + { + // 拔出设备, 清零标志位 + user_app.received_sofo_reset_cnt[port] = 0; + user_app.matebook_cnt_3s[port] = DELAY_3S; + user_app.equipment_is_matebook_x[port] = false; + } + +#endif +} + void gate3_control(bool enable) { log_info("gate3:%d\n", enable); @@ -548,16 +571,16 @@ void insertion_equipment_judgment(void) // 只有双口都连接才需要判断接入的设备是什么 - if(g_app_protocol_param[TYPEC_PORT0].pd_param.typec_status.typec_status == AttachedSRC - && g_app_protocol_param[TYPEC_PORT1].pd_param.typec_status.typec_status == AttachedSRC + if(user_app.type_c1_connect + && user_app.type_c2_connect && start_countdown_time) { start_countdown_time = false; user_app.c1_equipment_judgment_cnt = DELAY_1M; user_app.c2_equipment_judgment_cnt = DELAY_1M; } - else if(g_app_protocol_param[TYPEC_PORT0].pd_param.typec_status.typec_status != AttachedSRC - || g_app_protocol_param[TYPEC_PORT1].pd_param.typec_status.typec_status != AttachedSRC) + else if(!user_app.type_c1_connect + || !user_app.type_c2_connect) { start_countdown_time = true; user_app.c1_equipment_type = EQUIMENT_IS_PHONE; @@ -660,12 +683,16 @@ void mos_switch_control(void) case C2_A_INSER: // 等第一路电压调整到 第二路一样的电压 - if(abs(g_powerout_info[TYPEC_PORT1].set_vol - comp_adc_get_vin12(TYPEC_PORT0)) <= VOLTAGE_0P5V) + // 第二路需要设置的电压 - 第一路当前采集的电压 <= 500 + // 第二路需要设置的电压 - 第二路当前采集的电压 <= 500 + if((abs(g_powerout_info[TYPEC_PORT1].set_vol - comp_adc_get_vin12(TYPEC_PORT0)) <= VOLTAGE_0P5V) + && (abs(g_powerout_info[TYPEC_PORT1].set_vol - comp_adc_get_vin12(TYPEC_PORT1)) <= VOLTAGE_0P5V) + ) { user_app.need_switch_mos = false; log_info("%s %d\n", __func__, __LINE__); gate3_control(true); - drv_delay_ms(4); + drv_delay_ms(8); REG_ANALOG_GATE2->bf.driver_en = 0; REG_ANALOG_GATE2->bf.cp_en = 0; } @@ -682,7 +709,7 @@ void mos_switch_control(void) REG_ANALOG_GATE2->bf.driver_en = 1; REG_ANALOG_GATE2->bf.cp_en = 1; - drv_delay_ms(4); + drv_delay_ms(8); gate3_control(false); } @@ -691,6 +718,21 @@ void mos_switch_control(void) } +void wait_c2_ready(void) +{ + // 等gate3切换完之后, 再去开gate1 + if(user_app.wait_c2_switch_done + && (REG_ANALOG_GATE3->bf.driver_en == false)) + { + user_app.wait_c2_switch_done = false; + + if(user_app.type_c1_connect) + { + pd_phy_open_vbus(TYPEC_PORT0); + } + } +} + /* * @brief adapter_state_check * @param NULL @@ -705,8 +747,8 @@ void adapter_state_check(void) // 3个口的状态 - type_c1_state = (g_app_protocol_param[0].pd_param.typec_status.typec_status == AttachedSRC); - type_c2_state = (g_app_protocol_param[1].pd_param.typec_status.typec_status == AttachedSRC); + type_c1_state = user_app.type_c1_connect; + type_c2_state = user_app.type_c2_connect; usba_state = usba_online_state; if(type_c1_state && !type_c2_state && !usba_state) @@ -737,19 +779,42 @@ void adapter_state_check(void) { user_app.adapter_state = C1_C2_A_INSER; } + else + { + user_app.adapter_state = NO_INSERT; + } mos_switch_control(); + wait_c2_ready(); #if SWITCH_LINE_OFF_PROTECTION - if((user_app.protection_off_2s == 0) - && (g_powerout_info[TYPEC_PORT0].power_state == PWR_RDY) - && (g_powerout_info[TYPEC_PORT1].power_state == PWR_RDY) - && user_app.protection_off_flag) + // 如果是 C1 + C2状态, 还需要判断另外一个口不在调压状态,这样才能开启总的保护 + // 不然另外一个口调压途中开启了保护,会直接触发 + if(((g_powerout_info[TYPEC_PORT0].power_state == PWR_RDY) + || (g_powerout_info[TYPEC_PORT0].power_state == PWR_STANDBY)) + && ((g_powerout_info[TYPEC_PORT1].power_state == PWR_RDY) + || (g_powerout_info[TYPEC_PORT1].power_state == PWR_STANDBY)) + && (user_app.protection_off_2s[TYPEC_PORT0] == 0) + && user_app.protection_off_flag[TYPEC_PORT0] + ) { - user_app.protection_off_flag = false; + user_app.protection_off_flag[TYPEC_PORT0] = false; comp_powerout_protect_en(TYPEC_PORT0, true); + // log_info("port0_open_prote\n"); + } + + if(((g_powerout_info[TYPEC_PORT1].power_state == PWR_RDY) + || (g_powerout_info[TYPEC_PORT1].power_state == PWR_STANDBY)) + && ((g_powerout_info[TYPEC_PORT0].power_state == PWR_RDY) + || (g_powerout_info[TYPEC_PORT0].power_state == PWR_STANDBY)) + && (user_app.protection_off_2s[TYPEC_PORT1] == 0) + && user_app.protection_off_flag[TYPEC_PORT1] + ) + { + user_app.protection_off_flag[TYPEC_PORT1] = false; comp_powerout_protect_en(TYPEC_PORT1, true); + // log_info("port1_open_prote\n"); } #endif @@ -769,11 +834,14 @@ void adapter_state_check(void) } #if SWITCH_LINE_OFF_PROTECTION + // log_info("close_prote\n"); // 每次切换gate2和gate3的时候, 关闭2秒保护, 2秒后且在ready状态再打开 comp_powerout_protect_en(TYPEC_PORT0, false); comp_powerout_protect_en(TYPEC_PORT1, false); - user_app.protection_off_2s = DELAY_2S; - user_app.protection_off_flag = true; + user_app.protection_off_2s[TYPEC_PORT0] = DELAY_2S; + user_app.protection_off_2s[TYPEC_PORT1] = DELAY_2S; + user_app.protection_off_flag[TYPEC_PORT0] = true; + user_app.protection_off_flag[TYPEC_PORT1] = true; #endif if(user_app.update_adapter_state) @@ -784,7 +852,6 @@ void adapter_state_check(void) switch(user_app.adapter_state) { case NO_INSERT: - case A_INSER: // 恢复最大功率, 恢复全部协议 g_powerout_info[TYPEC_PORT0].support_protocol.byte = PROTOCOL_ALL_ENABLE; g_powerout_info[TYPEC_PORT1].support_protocol.byte = PROTOCOL_ALL_ENABLE; @@ -794,7 +861,29 @@ void adapter_state_check(void) app_protocol_reset(TYPEC_PORT1); gate3_control(false); user_app.need_switch_mos = false; - user_app.new_request_receive_done = false; + user_app.wait_c2_switch_done = false; + break; + + case A_INSER: + + // 从 有C口插入到没C口插入状态才清零一遍,不然休眠模式插着A口起机,执行了 + // app_protocol_reset 会让typeC状态机一直卡在等待连接 + if((user_app.last_adapter_state == C1_A_INSER) + || (user_app.last_adapter_state == C2_A_INSER) + || (user_app.last_adapter_state == C1_C2_A_INSER)) + { + // 恢复最大功率, 恢复全部协议 + g_powerout_info[TYPEC_PORT0].support_protocol.byte = PROTOCOL_ALL_ENABLE; + g_powerout_info[TYPEC_PORT1].support_protocol.byte = PROTOCOL_ALL_ENABLE; + + // 拔出时, 复位协议, 关闭gate3 + app_protocol_reset(TYPEC_PORT0); + app_protocol_reset(TYPEC_PORT1); + gate3_control(false); + user_app.need_switch_mos = false; + user_app.wait_c2_switch_done = false; + } + break; case C1_INSER: @@ -815,6 +904,9 @@ void adapter_state_check(void) g_powerout_info[TYPEC_PORT0].support_protocol.byte = PROTOCOL_ALL_ENABLE; g_powerout_info[TYPEC_PORT1].support_protocol.byte = PROTOCOL_ALL_ENABLE; + // 恢复C2口的SCP降额 + port1_scp_derate(false); + // 让第一路的电压电流和第二路的一样之后, 才把gate3打开, gate2关闭 comp_set_vol_cur(TYPEC_PORT0, g_powerout_info[TYPEC_PORT1].set_vol, @@ -833,6 +925,9 @@ void adapter_state_check(void) g_powerout_info[TYPEC_PORT0].support_protocol.byte = PROTOCOL_ALL_ENABLE; g_powerout_info[TYPEC_PORT1].support_protocol.byte = PROTOCOL_ALL_ENABLE; + // 恢复C2口的SCP降额 + port1_scp_derate(false); + // 1. 接入优先级 if(user_app.c1_priority_inser) { @@ -927,14 +1022,14 @@ void adapter_state_check(void) if(g_powerout_info[TYPEC_PORT1].protocol_type == PROTOCOL_PD) { // 发送新src_cap 等C2的负载主动申请完之后,再去切mos - user_app.new_request_receive_done = true; + user_app.wait_c2_switch_done = true; user_app.need_switch_mos = true; } else // 其他协议都是小功率, 直接切mos { REG_ANALOG_GATE2->bf.driver_en = 1; REG_ANALOG_GATE2->bf.cp_en = 1; - drv_delay_ms(4); + drv_delay_ms(8); gate3_control(false); } } @@ -943,7 +1038,7 @@ void adapter_state_check(void) // 1. 确保gate3是关闭的 REG_ANALOG_GATE2->bf.driver_en = 1; REG_ANALOG_GATE2->bf.cp_en = 1; - drv_delay_ms(4); + drv_delay_ms(8); gate3_control(false); } @@ -972,6 +1067,9 @@ void adapter_state_check(void) need_send_cap_flag[TYPEC_PORT1] = PD_PWR_65W; } + // 恢复C2口的SCP降额 + port1_scp_derate(false); + // 让第一路的电压电流和第二路的一样之后, 才把gate3打开, gate2关闭 comp_set_vol_cur(TYPEC_PORT0, g_powerout_info[TYPEC_PORT1].set_vol, @@ -986,14 +1084,18 @@ void adapter_state_check(void) need_send_cap_flag[TYPEC_PORT0] = PD_PWR_45W; need_send_cap_flag[TYPEC_PORT1] = PD_PWR_12W; - // 复位DPDN协议以及只留PD协议 - charge_protocol_reset(TYPEC_PORT1, &g_app_protocol_param[TYPEC_PORT1].dpdn_param, - SCP_TYPEC_RESET); - g_powerout_info[TYPEC_PORT1].support_protocol.byte = PROTOCOL_ONLY_ENABLE_PD; + // 只关QC。 PD通过发src_cap降额, SCP通过降额寄存器进行降额 + g_powerout_info[TYPEC_PORT1].support_protocol.qc_support = 0; - // 如果C2原本就升到了5V以上电压, 要降回5V。 PD会自己回5V, DPDN协议就需要手动设回去 - if(g_powerout_info[TYPEC_PORT1].protocol_type != PROTOCOL_PD) + // C1口进行SCP降额 + port1_scp_derate(true); + + // 如果是 PD,则不主动回5V。 如果是SCP,也不主动回5V, 如果是QC,才主动回5V + if(g_powerout_info[TYPEC_PORT1].protocol_type == PROTOCOL_QC) { + // 复位DPDN协议, 把C2口主动调回5V + charge_protocol_reset(TYPEC_PORT1, &g_app_protocol_param[TYPEC_PORT1].dpdn_param, + SCP_TYPEC_RESET); comp_powerout_default_set(TYPEC_PORT1, &g_powerout_info[TYPEC_PORT1]); } @@ -1021,7 +1123,7 @@ void adapter_state_check(void) if(g_powerout_info[TYPEC_PORT1].protocol_type == PROTOCOL_PD) { // 发送新src_cap 等C2的负载主动申请完之后,再去切mos - user_app.new_request_receive_done = true; + user_app.wait_c2_switch_done = true; user_app.need_switch_mos = true; } else // 其他协议都是小功率, 直接切mos @@ -1029,7 +1131,7 @@ void adapter_state_check(void) // 先关再开, 防止功率并联反灌 REG_ANALOG_GATE2->bf.driver_en = 1; REG_ANALOG_GATE2->bf.cp_en = 1; - drv_delay_ms(4); + drv_delay_ms(8); gate3_control(false); } } @@ -1037,7 +1139,7 @@ void adapter_state_check(void) { REG_ANALOG_GATE2->bf.driver_en = 1; REG_ANALOG_GATE2->bf.cp_en = 1; - drv_delay_ms(4); + drv_delay_ms(8); gate3_control(false); } @@ -1091,10 +1193,10 @@ void adapter_state_check(void) } } - // log_info("adapter_state:%d port0:%d port1:%d\n", - // user_app.adapter_state, - // need_send_cap_flag[TYPEC_PORT0], - // need_send_cap_flag[TYPEC_PORT1]); + log_info("adapter_state:%d port0:%d port1:%d\n", + user_app.adapter_state, + need_send_cap_flag[TYPEC_PORT0], + need_send_cap_flag[TYPEC_PORT1]); user_app.last_adapter_state = user_app.adapter_state; #if USER_NTC_ENABLE @@ -1605,6 +1707,68 @@ void comp_port_connect_state_check(uint8_t port) } +#if HUAWEI_MATEBOOK_X +// 该函数一定要放在 prl 和 pe层中间 +void solve_huawei_matebook(uint8_t port, pd_param_s* pd_param) +{ + // prl层收到sofo_reset会把 pe_softreset_recived_from_prl = true + // pe层时会把 pe_softreset_recived_from_prl = false + if(pd_param->pd_flags.pd_pe_event_flag.bits.pe_softreset_recived_from_prl) + { + if(user_app.received_sofo_reset_cnt[port] == 0) + { + user_app.matebook_cnt_3s[port] = DELAY_3S; + } + + user_app.received_sofo_reset_cnt[port]++; + } + + // 如果三秒内连续收到3次, 则认为是该华为笔记本 + if((user_app.matebook_cnt_3s[port] != 0) + && user_app.received_sofo_reset_cnt[port] >= 3) + { + user_app.equipment_is_matebook_x[port] = true; + user_app.matebook_cnt_3s[port] = 0; + + if(port == TYPEC_PORT0) + { + port0_pd_src_cap_init(pd_param, need_send_cap_flag[TYPEC_PORT0]); + } + else + { + port1_pd_src_cap_init(pd_param, need_send_cap_flag[TYPEC_PORT1]); + } + + // 更新后还必须发一次软复位或者硬复位, 这笔记本才会去申请电压 + // pd_param->pd_flags.pd_pe_event_flag.bits.pe_hardreset_recived_from_prl = true; + // pd_param->pd_pe_status.pe_status = PE_SRC_Hard_Reset; + // pd_param->pd_pe_status.pe_process_status = pd_entry_status; + + // pd_param->pd_pe_status.pe_process_status = pd_entry_status; + // PE_SRC_Transition_to_default_action(port, pd_param); + + pd_param->pd_flags.pd_process_flag.bits.ams_start_flag = true; + pd_param->pd_pe_status.pe_process_status = pd_entry_status; + pd_param->pd_pe_status.pe_status = PE_SRC_Send_Soft_Reset; + PE_SRC_Send_Soft_Reset_action(port, pd_param); + + log_info("port:[%d] is_matebook\n", port); + } + + // 倒计时结束, 收到的sofo_reset少于3次 + if((user_app.matebook_cnt_3s[port] == 0) + && (user_app.received_sofo_reset_cnt[port] < 3)) + { + user_app.equipment_is_matebook_x[port] = false; + user_app.received_sofo_reset_cnt[port] = 0; + // log_info("*"); + } + + // 拔出设备时要清零标志位, 这个在拔出typec时做, 这个函数放在prl和pe中间的话 + // 是只有typec已连接才会跑 +} +#endif + void port_inser_priority_judgment(void) { // 只有 C1 + C2 同在时才需要判接入优先级, 所以单口时不需要清零 @@ -1650,6 +1814,14 @@ void port_inser_priority_judgment(void) } } +void typec_state_update(void) +{ + user_app.type_c1_connect = ((g_app_protocol_param[0].pd_param.typec_status.typec_status == AttachedSRC) + || (g_app_protocol_param[0].pd_param.typec_status.typec_status == UnattachWaitSRC)); + user_app.type_c2_connect = ((g_app_protocol_param[1].pd_param.typec_status.typec_status == AttachedSRC) + || (g_app_protocol_param[1].pd_param.typec_status.typec_status == UnattachWaitSRC)); +} + /* * @brief app_protocol_run * @param null @@ -1669,23 +1841,17 @@ void app_protocol_run(uint8_t port) // } typec_run(port, &g_app_protocol_param[port].pd_param); - /* - static uint8_t new_state = 0, old_state = 0xff; - new_state = g_app_protocol_param[TYPEC_PORT0].pd_param.typec_status.typec_status; - if(old_state != new_state) - { - old_state = new_state; - log_info("port0_typec:%d\n", old_state); - } + static uint8_t new_state = 0, old_state = 0xff; + new_state = g_app_protocol_param[TYPEC_PORT0].pd_param.typec_status.typec_status; - if(system_1s_cnt) - { - system_1s_cnt = 0; - log_info("cc_status:%d\n", - g_app_protocol_param[TYPEC_PORT0].pd_param.pd_callback2->pd_phy_get_cc_status(port, &g_app_protocol_param[TYPEC_PORT0].pd_param)); - } - */ + if(old_state != new_state) + { + old_state = new_state; + log_info("port0_typec:%d\n", old_state); + } + + typec_state_update(); // 端口接入优先级判断 port_inser_priority_judgment(); diff --git a/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/src/port0_customized.c b/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/src/port0_customized.c index c090651..805083d 100644 --- a/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/src/port0_customized.c +++ b/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/src/port0_customized.c @@ -325,8 +325,8 @@ const scp_def_vol_s PORT0_SCP_DEF_VOL[] = //scp power curve for 0xd0~0xdf. const scp_power_curve_s PORT0_SCP_POWER_CURVE_BUF[] = { - {VOLTAGE_9V, CURRENT_2P7A}, - {VOLTAGE_10V, CURRENT_2P4A}, + {VOLTAGE_9V, CURRENT_2P5A}, + {VOLTAGE_10V, CURRENT_2P25A}, // {VOLTAGE_10P5V, CURRENT_2P2A}, // {VOLTAGE_12V, CURRENT_1P7A}, }; @@ -923,6 +923,22 @@ void port0_pd_src_cap_init(pd_param_s*pd_param, uint8_t pwr_cnt) //src ext pd_param->pd_assist.pd_scedb.scedb_bits.src_pdp = p_cap->src_pdp; +#if HUAWEI_MATEBOOK_X + + // 如果是华为matebook_x, 则把PPS档去掉 + if(user_app.equipment_is_matebook_x[TYPEC_PORT0]) + { + if(p_cap->src_pdp >= 25) + { + pd_param->pd_assist.src_cap_send.pdo_cnt = 5; + + // 去掉pps + pd_param->pd_assist.src_cap_send.pd_pdos[5].data32 = 0; + pd_param->pd_assist.src_cap_send.pd_pdos[6].data32 = 0; + } + } + +#endif //pps status pd_param->pd_assist.pd_ppssdb.byte[0] = 0xff; diff --git a/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/src/port1_customized.c b/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/src/port1_customized.c index a26e567..c1256ee 100644 --- a/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/src/port1_customized.c +++ b/PD_CPS8860_A1_CPS_Common_Demo/ac_project/code/src/port1_customized.c @@ -325,8 +325,8 @@ const scp_def_vol_s PORT1_SCP_DEF_VOL[] = //scp power curve for 0xd0~0xdf. const scp_power_curve_s PORT1_SCP_POWER_CURVE_BUF[] = { - {VOLTAGE_9V, CURRENT_2P7A}, - {VOLTAGE_10V, CURRENT_2P4A}, + {VOLTAGE_9V, CURRENT_2P5A}, + {VOLTAGE_10V, CURRENT_2P25A}, // {VOLTAGE_10P5V, CURRENT_2P2A}, // {VOLTAGE_12V, CURRENT_1P7A}, }; @@ -347,6 +347,23 @@ const scp_cap_features_s PORT1_SCP_CAP_FEATURES = .cur_reg55 = 0x00, }; +void port1_scp_derate(bool en) +{ + if(en) + { + // 降到 4/8。 bit0代表是否降额, 1~3代表降多少, 4~7保留置0 + // g_app_protocol_param[TYPEC_PORT1].dpdn_param.qc_scp_param.scp_param.scp_prl_passist.register_value[0xa5] = 0x9; + g_app_protocol_param[TYPEC_PORT1].dpdn_param.qc_scp_param.scp_param.scp_app_passist.derating_ratio = 0x9; + } + else + { + // g_app_protocol_param[TYPEC_PORT1].dpdn_param.qc_scp_param.scp_param.scp_prl_passist.register_value[0xa5] = 0; + g_app_protocol_param[TYPEC_PORT1].dpdn_param.qc_scp_param.scp_param.scp_app_passist.derating_ratio = 0; + } + + // log_info("port1_scp_derate:%d\n", en); +} + /* * @brief port1_scp_register_attr_upgrade * @param scp_param @@ -921,6 +938,21 @@ void port1_pd_src_cap_init(pd_param_s*pd_param, uint8_t pwr_cnt) //src ext pd_param->pd_assist.pd_scedb.scedb_bits.src_pdp = p_cap->src_pdp; +#if HUAWEI_MATEBOOK_X + + // 如果是华为matebook_x, 则把PPS档去掉 + if(user_app.equipment_is_matebook_x[TYPEC_PORT1]) + { + // 该项目的PDO支持PPS档的 cnt都有5个, 所以直接 = 5, 也可以不用判src_pdp + if(p_cap->src_pdp >= 25) + { + pd_param->pd_assist.src_cap_send.pdo_cnt = 5; + pd_param->pd_assist.src_cap_send.pd_pdos[5].data32 = 0; + pd_param->pd_assist.src_cap_send.pd_pdos[6].data32 = 0; + } + } + +#endif //pps status pd_param->pd_assist.pd_ppssdb.byte[0] = 0xff; diff --git a/PD_CPS8860_A1_CPS_Common_Demo/ac_project/project/Objects/CPS8860_anker_9196.axf b/PD_CPS8860_A1_CPS_Common_Demo/ac_project/project/Objects/CPS8860_anker_9196.axf index 3646316..1af5a68 100644 Binary files a/PD_CPS8860_A1_CPS_Common_Demo/ac_project/project/Objects/CPS8860_anker_9196.axf and b/PD_CPS8860_A1_CPS_Common_Demo/ac_project/project/Objects/CPS8860_anker_9196.axf differ diff --git a/PD_CPS8860_A1_CPS_Common_Demo/ac_project/project/Objects/CPS8860_anker_9196.build_log.htm b/PD_CPS8860_A1_CPS_Common_Demo/ac_project/project/Objects/CPS8860_anker_9196.build_log.htm index 4151e49..1ed05e6 100644 --- a/PD_CPS8860_A1_CPS_Common_Demo/ac_project/project/Objects/CPS8860_anker_9196.build_log.htm +++ b/PD_CPS8860_A1_CPS_Common_Demo/ac_project/project/Objects/CPS8860_anker_9196.build_log.htm @@ -30,17 +30,24 @@ Rebuild target 'Target 1' compiling adapter_antifake.c... assembling startup_CMSDK_CM0.s... compiling system_CMSDK_CM0.c... -compiling main.c... -compiling cps8860_it.c... +compiling comp_adc.c... compiling app_spec.c... ..\..\common\app\src\app_spec.c(177): warning: #177-D: variable "umask_val" was declared but never referenced uint32_t umask_val = 0; ..\..\common\app\src\app_spec.c: 1 warning, 0 errors -compiling comp_adc.c... compiling comp_primary_side.c... +compiling cps8860_it.c... compiling port0_customized.c... compiling port1_customized.c... compiling comp_auto_zero.c... +compiling main.c... +compiling comp_discharge.c... +compiling comp_powerout.c... +compiling comp_dac.c... +..\code\src\comp_dac.c(311): warning: #177-D: variable "temp" was declared but never referenced + uint32_t temp[TYPEC_PORT_MAX + 1] = {0}; +..\code\src\comp_dac.c: 1 warning, 0 errors +compiling comp_protection.c... compiling customized.c... ..\code\src\customized.c(26): warning: #188-D: enumerated type mixed with another type adapter_info_s g_adapter_info = {0}; @@ -48,27 +55,20 @@ compiling customized.c... user_app_s user_app = {0}; ..\code\src\customized.c(175): warning: #177-D: function "path_scp_mode_exit_action" was declared but never referenced static void path_scp_mode_exit_action(uint8_t port, scp_param_s *scp_param) -..\code\src\customized.c(1437): warning: #177-D: function "comp_ccloop_enable" was declared but never referenced +..\code\src\customized.c(1539): warning: #177-D: function "comp_ccloop_enable" was declared but never referenced static void comp_ccloop_enable(uint8_t port) ..\code\src\customized.c: 4 warnings, 0 errors -compiling comp_discharge.c... -compiling comp_protection.c... -compiling comp_powerout.c... -compiling comp_dac.c... -..\code\src\comp_dac.c(307): warning: #177-D: variable "temp" was declared but never referenced - uint32_t temp[TYPEC_PORT_MAX + 1] = {0}; -..\code\src\comp_dac.c: 1 warning, 0 errors compiling dpdn_protocol.c... compiling qc_scp_protocol.c... compiling ufcs_protocol.c... compiling pd_protocol.c... -..\..\common\comp\protocol\pd_protocol\src\pd_protocol.c(816): warning: #550-D: variable "pd_hw_uvdm_header" was set but never used +..\..\common\comp\protocol\pd_protocol\src\pd_protocol.c(827): warning: #550-D: variable "pd_hw_uvdm_header" was set but never used pd_hw_uvdm_header_u pd_hw_uvdm_header = {0}; -..\..\common\comp\protocol\pd_protocol\src\pd_protocol.c(287): warning: #177-D: function "pd_analog_set" was declared but never referenced +..\..\common\comp\protocol\pd_protocol\src\pd_protocol.c(275): warning: #177-D: function "pd_analog_set" was declared but never referenced static void pd_analog_set(uint8_t port) ..\..\common\comp\protocol\pd_protocol\src\pd_protocol.c: 2 warnings, 0 errors linking... -Program Size: Code=11602 RO-data=1846 RW-data=60 ZI-data=3848 +Program Size: Code=13594 RO-data=1866 RW-data=60 ZI-data=3864 FromELF: creating hex file... After Build - User command #1: .\CPS8860.bat C:\Users\TJP\Desktop\GIT_TEST\CPS8860_9196_70W\Anker_9196_CPS8860\PD_CPS8860_A1_CPS_Common_Demo\ac_project\project>set Project_Name=CPS8860_anker_9196 @@ -116,11 +116,11 @@ out_type : expected out file type 'd' output binary file(.bin) [out_file_name_without_postfix] : Option: out file name without postfix. ---------------------------------------------------------------------- -input code size: 13,508 [13.191K] - app size: 34C8 ; CRC: 113C +input code size: 15,520 [15.156K] + app size: 3CA4 ; CRC: 149B -out code size : 13,512 [13.195K] -create file: .\output\CPS8860_anker_9196_A1_60_V0.6_CRCCA5F.hex success! +out code size : 15,524 [15.160K] +create file: .\output\CPS8860_anker_9196_A1_60_V0.7_CRC1EBD.hex success! C:\Users\TJP\Desktop\GIT_TEST\CPS8860_9196_70W\Anker_9196_CPS8860\PD_CPS8860_A1_CPS_Common_Demo\ac_project\project>move /Y .\CPS8860_anker_9196_*.hex .\output һļҲļ ".\Objects\CPS8860_anker_9196.axf" - 0 Error(s), 8 Warning(s). @@ -136,7 +136,7 @@ Package Vendor: ARM D:\Keil_v5\ARM\PACK\ARM\CMSIS\5.8.0\Device\ARM\ARMCM0\Include

Collection of Component Files used:

-Build Time Elapsed: 00:00:06 +Build Time Elapsed: 00:00:13 diff --git a/PD_CPS8860_A1_CPS_Common_Demo/ac_project/project/Objects/CPS8860_anker_9196.htm b/PD_CPS8860_A1_CPS_Common_Demo/ac_project/project/Objects/CPS8860_anker_9196.htm index 527da7b..861dbe9 100644 --- a/PD_CPS8860_A1_CPS_Common_Demo/ac_project/project/Objects/CPS8860_anker_9196.htm +++ b/PD_CPS8860_A1_CPS_Common_Demo/ac_project/project/Objects/CPS8860_anker_9196.htm @@ -3,17 +3,18 @@ Static Call Graph - [.\Objects\CPS8860_anker_9196.axf]

Static Call Graph for image .\Objects\CPS8860_anker_9196.axf


-

#<CALLGRAPH># ARM Linker, 5060960: Last Updated: Wed Jul 02 19:44:17 2025 +

#<CALLGRAPH># ARM Linker, 5060960: Last Updated: Wed Jul 09 09:27:44 2025

-

Maximum Stack Usage = 240 bytes + Unknown(Cycles, Untraceable Function Pointers)

+

Maximum Stack Usage = 320 bytes + Unknown(Cycles, Untraceable Function Pointers)

Call chain for Maximum Stack Depth:

-main ⇒ app_spec_run ⇒ app_protocol_run ⇒ dpdn_protocol_run ⇒ fast_charge_reset ⇒ comp_powerout_open_nmos ⇒ comp_dac_open_vbus ⇒ comp_set_vol_cur ⇒ comp_powerout_cur_set ⇒ comp_set_output_current ⇒ comp_dac_cc_target_set ⇒ comp_dac_cc_acdc ⇒ comp_dac_cc_2dcdc_fb +main ⇒ app_spec_run ⇒ app_protocol_run ⇒ adapter_state_check ⇒ wait_c2_ready ⇒ pd_phy_open_vbus ⇒ adapter_state_check (Cycle)

Mutually Recursive functions

  • SVC_Handler   ⇒   SVC_Handler
  • PendSV_Handler   ⇒   PendSV_Handler
  • CCX_OVP_Handler   ⇒   CCX_OVP_Handler
    +
  • pd_phy_open_vbus   ⇒   adapter_state_check

    @@ -115,99 +116,141 @@ Global Symbols

    CHIP_OT_Handler (Thumb, 0 bytes, Stack size 0 bytes, rom_symdef.txt(ABSOLUTE), UNUSED)
    [Address Reference Count : 1]

    -

    __aeabi_uidivmod (Thumb, 0 bytes, Stack size 0 bytes, rom_symdef.txt(ABSOLUTE)) -

    [Called By]