Live2D

0606

今日份总结

  • PD协议

    • 适配器和主机之间都存在着超时机制,在30ms内未答复会触发hardreset,

      比如:适配器发送消息后,会等待主机发送good RCR,收到消息后开始启动定时器,这个时候如果30ms未答复则定义为超时

  • 问题:在电池过放的时候进行PD充电,发现几分钟会触发hardreset同时适配器无法升压

    • 目前怀疑是:pd通讯准备工作完成后发送的消息给到CP,CP策略中的notifier还未注册,这时便不会再去走调压策略,从而pd快充中断,只有5V2A

    • 这次的hardreset属于pd协议中的正常行为,

    • tcpc会初始化一个通知链,rt_pd_manager.c(pd会注册pd_tcp_notifier_call通知块),pd_policy_manager.c(cp策略中会注册pca_pps_tcp_notifier_call通知块),主充会注册一个通知块

      • 当tcpc硬件通讯完成后发送事件,通知链会发出通知(执行通知链中所有元素的回调函数)

      • 问题是在事件发生时,pd_policy_manager中的通知块还没有挂载上去,因此回调函数pca_pps_tcp_notifier_call不会执行

        // 回调中针对is_pps_en_unlock进行初始化
        case PD_CONNECT_PE_READY_SNK_APDO:
            if (__pdpm->hrst_cnt < 5) {
                pr_err("en unlock\n");
                __pdpm->is_pps_en_unlock = true;
            }
            break;
        power_supply_changed(__pdpm->usb_psy)
        

        问题分析:

        • 18s的时候pd那边通知块回调已经开始执行,说明事件已经触发
        • 22s的时候cp策略的probe才跑完,说明这个时候通知块才挂载上

        • 正常的应该如此:通知链上挂载的通知块回调函数依次执行

      问题:1. pd通讯完成的标志是什么?在代码中哪里?有什么log打印?

      pd协议包中适配器source端发送ps_rdy消息,准确讲是tcpc通讯完成,pd也是会注册通知块接收事件去执行,搜索三个回调函数是否有打印log

      case PD_CONNECT_PE_READY_SNK_APDO:
      	ret = tcpm_inquire_dpm_flags(rpmd->tcpc);
      	pr_err(" set RT1711_PD_ACTIVE\n");
      case PD_CONNECT_PE_READY_SRC:
      case PD_CONNECT_PE_READY_SRC_PD30:
      	pd_sink_set_vol_and_cur(rpmd, rpmd->sink_mv_old,
      			rpmd->sink_ma_old,
      			TCP_VBUS_CTRL_PD_STANDBY);
      	typec_set_pwr_opmode(rpmd->typec_port,TYPEC_PWR_MODE_PD);
      	if (!rpmd->partner)
      		break;
      	ret = tcpm_inquire_pd_partner_inform(rpmd->tcpc,partner_vdos);
      		if (ret != TCPM_SUCCESS)
      			break;
      		rpmd->partner_identity.id_header = partner_vdos[0];
      		rpmd->partner_identity.cert_stat = partner_vdos[1];
      		rpmd->partner_identity.product = partner_vdos[2];
      		typec_partner_set_identity(rpmd->partner);
      		break;
      	};
      break;
      
      1. 这个消息是通知到哪里?cp如何接收?

      消息是通过通知链机制进行通知,cp会有一个通知块挂载到通知链条上

      1. 关机充电启动的时候会发生一次hardreset,这次hardreset引起的原因和是否有解决措施
        • 关机启动时会发生一次
        • 关机充电其实kernel已经跑起来了,这个时候该注册的通知块,通知链都已经初始化完成了

pd通讯-->适配器和主机

修改方案

  • pd提供出来一个获取pps状态的接口

  • 在pd_policy_manager.c中通知块初始化后去获取pps状态

  • 如果此时已经满足条件,相当于事件已经发送那就直接去执行原流程中回调函数会执行的动作

    pd_policy_manager.c		usbpd_pm_probe()
       ret = tcpm_get_pd_connect_state(tcpc);
    	if(ret == PD_CONNECT_PE_READY_SNK_APDO){
    		pr_err("en unlock\n");
    		pdpm->is_pps_en_unlock = true;
    		power_supply_changed(pdpm->usb_psy);
    	}
    
    tcpm.c
    uint8_t tcpm_get_pd_connect_state(struct tcpc_device *tcpc)
    {
        struct pd_port *pd_port = &tcpc->pd_port;
    
        if (pd_port->power_role == PD_ROLE_SOURCE) {
            if (pd_check_rev30(pd_port))
                return PD_CONNECT_PE_READY_SRC_PD30;
    
            return PD_CONNECT_PE_READY_SRC;
        }
    
        if (pd_check_rev30(pd_port)) {
            if (pd_is_source_support_apdo(pd_port))
                return PD_CONNECT_PE_READY_SNK_APDO;
    
            return PD_CONNECT_PE_READY_SNK_PD30;
        }
    
        return PD_CONNECT_PE_READY_SNK;
    }
    EXPORT_SYMBOL(tcpm_get_pd_connect_state);
    

pd

  • pd中的消息可分为

    • 控制消息:pd_ctrl_msg_name

    • 数据消息:pd_data_msg_name

    • 硬件消息:pd_hw_msg_name

      static const char *const pd_hw_msg_name[] = {
      	"Detached",
      	"Attached",
      	"hard_reset",
      	"vbus_high",
      	"vbus_low",
      	"vbus_0v",
      	"vbus_stable",
      	"tx_err",
      	"discard",
      }
      

函数追查

pd_tcp_notifier_call
    rpmd->pd_nb.notifier_call = pd_tcp_notifier_call;
	ret = register_tcp_dev_notifier(rpmd->tcpc, &rpmd->pd_nb,
					TCP_NOTIFY_TYPE_ALL);
posted @ 2023-06-06 01:49  Mikasae  阅读(405)  评论(0)    收藏  举报