typec tcpm状态机工作原理

一、 概要

  在移动平台大部分会需要使用typec,而typec包含充电、语音和usb的功能,所以状态机管理器会显得比较复杂难懂,这里系统的梳理了一下关于该状态机的初始化和工作原理,以及一些简单case的数据流程。

二、 介绍

  1. 什么是TCPM?
      TCPM英文全称为USB Type-C Port Manager,即USB Type-C 端口管理器。TCPC是一个功能管理模块,包括VBUS和VCONN电源管理以及USB PD通信的设备策略管理层、策略引擎层和部分协议层等。

  2. 什么是TCPC?
      TCPC英文全称为USB Type-C Port Controller,即USB Type-C 端口控制器。TCPC是一个功能控制模块,包括VBUS和VCONN电源控制、USB Type-C CC逻辑以及USB PD通信 BMC物理层和部分协议层等。

  3. 什么是TCPCI?
      TCPCI英文全称为USB Type-C Port Controller Interface ,即USB Type-C 端口控制器接口。TCPCI的目的是在TCPC和TCPM之间提供定义的接口,以便标准化和简化TCPM实现。TCPCI除了规定的内容,还包含了供应商自定义内容,用于供应商进行相应的功能扩展。

三、 tcpm的工作细节

  在我们平时工作中adb使用typec口,来进行调试是常有的事情,那么在typec插上的一瞬间是就是通过tcpm来建立最初的联系,然后通知到dwc3和gadget来进行交互的,后面的工作就完全交给dwc3那边进行处理。
  可以从/sys/kernel/debug/usb/tcpm-xxx下,抓取一份tcpm的log,这里抓取了一份RK平台,从开机到adb数据线设备插拔的过程log,来分析整个数据流程:

	1. 一些重要参数的初始化值
	port->port_type = TYPEC_PORT_DRP
	port->prefer_role = TYPEC_SINK
	port->data_role = TYPEC_DEVICE;
	port->pwr_role = TYPEC_SINK;
	port->try_role = TYPEC_SINK;

	port->state = SNK_UNATTACHED
	port->vbus_never_low = false
	port->pd_capable = false
	tcpm_rp_cc(port) = TYPEC_CC_RP_3_0

	2. 一些重要参数的变动
	port->vbus_present = false -> _tcpm_pd_vbus_on() -> ture
	port->vbus_vsafe0v = true -> _tcpm_pd_vbus_on() -> false

	3. 状态机转变state的整个调用流程
	tcpm_set_state -> kthread_queue_work(port->wq, &port->state_machine) 
	--> tcpm_state_machine_work -> run_state_machine

	4. 抓取到的整个数据流程包含tcpm初始化,插入/拔出adb数据线
	rk3568_s:/sys/kernel/debug/usb/tcpm-0-004e # cat log
	// 开机时启动后,初始阶段的log
	[    3.169614] init extcon finished
	[    3.173249] Setting usb_comm capable false
	[    3.174716] Setting voltage/current limit 0 mV 0 mA
	[    3.174728] polarity 0
	[    3.176800] Requesting mux state 0, usb-role 0, orientation 0
	[    3.178567] state change INVALID_STATE -> SNK_UNATTACHED [rev1 NONE_AMS]
	[    3.179503] CC1: 0 -> 0, CC2: 0 -> 0 [state SNK_UNATTACHED, polarity 0, disconnected]
	[    3.179510] state change SNK_UNATTACHED -> PORT_RESET [rev1 NONE_AMS]
	[    3.179520] 0-004e: registered
	[    3.179530] Setting usb_comm capable false
	[    3.181007] Setting voltage/current limit 0 mV 0 mA
	[    3.181023] polarity 0
	[    3.183097] Requesting mux state 0, usb-role 0, orientation 0
	[    3.184351] cc:=0
	[    3.185144] pending state change PORT_RESET -> PORT_RESET_WAIT_OFF @ 100 ms [rev1 NONE_AMS]
	[    3.185154] state change PORT_RESET -> PORT_RESET_WAIT_OFF [delayed 100 ms]
	[    3.185159] state change PORT_RESET_WAIT_OFF -> SNK_UNATTACHED [rev1 NONE_AMS]
	[    3.185163] Start toggling
	[    3.185831] state change SNK_UNATTACHED -> TOGGLING [rev1 NONE_AMS]

	//插入typec后,tcpm的log,其中"======>" 这种箭头的打印是我本人加的
	[   53.680304][  T152] =================> tcpci_irq -> status[0x02]
	[   53.681360] VBUS on
	[   53.705497][  T152] =================> tcpci_irq -> status[0x01]
	[   53.706613] CC1: 0 -> 3, CC2: 0 -> 0 [state TOGGLING, polarity 0, connected]
	[   53.706627] state change TOGGLING -> SNK_ATTACH_WAIT [rev1 NONE_AMS]
	[   53.706644] pending state change SNK_ATTACH_WAIT -> SNK_DEBOUNCED @ 200 ms [rev1 NONE_AMS]
	[   53.906677] state change SNK_ATTACH_WAIT -> SNK_DEBOUNCED [delayed 200 ms]
	[   53.906691] state change SNK_DEBOUNCED -> SNK_ATTACHED [rev1 NONE_AMS]
	[   53.906695] polarity 0
	[   53.908791][  T151] emdoor: tcpm_set_polarity typec positive
	[   53.908862] Requesting mux state 1, usb-role 2, orientation 1
	[   53.909477][  T151] husb311 0-004e: CC connected in CC1 as UFP
	[   53.909744] state change SNK_ATTACHED -> SNK_STARTUP [rev1 NONE_AMS]
	[   53.909755] state change SNK_STARTUP -> SNK_DISCOVERY [rev3 NONE_AMS]
	[   53.909759] Setting voltage/current limit 5000 mV 0 mA
	[   53.909775] vbus=0 charge:=1
	[   53.910560] state change SNK_DISCOVERY -> SNK_WAIT_CAPABILITIES [rev3 NONE_AMS]
	[   53.910951] pending state change SNK_WAIT_CAPABILITIES -> HARD_RESET_SEND @ 310 ms [rev3 NONE_AMS]
	[   54.221059] state change SNK_WAIT_CAPABILITIES -> HARD_RESET_SEND [delayed 310 ms]
	[   54.221080] AMS HARD_RESET start
	[   54.221083] PD TX, type: 0x5
	[   54.223648][  T152] =================> tcpci_irq -> status[0x50]
	[   54.223737] PD TX complete, status: 0
	[   54.223819] state change HARD_RESET_SEND -> HARD_RESET_START [rev3 HARD_RESET]
	[   54.225211] state change HARD_RESET_START -> SNK_HARD_RESET_SINK_OFF [rev3 HARD_RESET]
	[   54.225235] vconn:=0
	[   54.225747] Requesting mux state 1, usb-role 2, orientation 1
	[   54.226346] pending state change SNK_HARD_RESET_SINK_OFF -> SNK_HARD_RESET_SINK_ON @ 650 ms [rev3 HARD_RESET]
	[   54.876427] state change SNK_HARD_RESET_SINK_OFF -> SNK_HARD_RESET_SINK_ON [delayed 650 ms]
	[   54.876447] AMS HARD_RESET finished
	[   54.876850] state change SNK_HARD_RESET_SINK_ON -> SNK_STARTUP [rev3 NONE_AMS]
	[   54.876871] state change SNK_STARTUP -> SNK_DISCOVERY [rev3 NONE_AMS]
	[   54.876875] Setting voltage/current limit 5000 mV 0 mA
	[   54.876896] state change SNK_DISCOVERY -> SNK_WAIT_CAPABILITIES [rev3 NONE_AMS]
	[   54.877264] pending state change SNK_WAIT_CAPABILITIES -> HARD_RESET_SEND @ 310 ms [rev3 NONE_AMS]
	[   55.187319] state change SNK_WAIT_CAPABILITIES -> HARD_RESET_SEND [delayed 310 ms]
	[   55.187339] AMS HARD_RESET start
	[   55.187343] PD TX, type: 0x5
	[   55.189910][  T152] =================> tcpci_irq -> status[0x50]
	[   55.189982] PD TX complete, status: 0
	[   55.190020] state change HARD_RESET_SEND -> HARD_RESET_START [rev3 HARD_RESET]
	[   55.191474] state change HARD_RESET_START -> SNK_HARD_RESET_SINK_OFF [rev3 HARD_RESET]
	[   55.191494] vconn:=0
	[   55.192023] Requesting mux state 1, usb-role 2, orientation 1
	[   55.192727] pending state change SNK_HARD_RESET_SINK_OFF -> SNK_HARD_RESET_SINK_ON @ 650 ms [rev3 HARD_RESET]
	[   55.842808] state change SNK_HARD_RESET_SINK_OFF -> SNK_HARD_RESET_SINK_ON [delayed 650 ms]
	[   55.842828] AMS HARD_RESET finished
	[   55.843201] state change SNK_HARD_RESET_SINK_ON -> SNK_STARTUP [rev3 NONE_AMS]
	[   55.843214] state change SNK_STARTUP -> SNK_DISCOVERY [rev3 NONE_AMS]
	[   55.843217] Setting voltage/current limit 5000 mV 0 mA
	[   55.843238] state change SNK_DISCOVERY -> SNK_WAIT_CAPABILITIES [rev3 NONE_AMS]
	[   55.843604] pending state change SNK_WAIT_CAPABILITIES -> SNK_READY @ 310 ms [rev3 NONE_AMS]
	[   56.153719] state change SNK_WAIT_CAPABILITIES -> SNK_READY [delayed 310 ms]

	// 拔出typec时,tcpm的打印
	[ 2087.027300][  T152] =================> tcpci_irq -> status[0x01]
	[ 2087.028556] CC1: 3 -> 0, CC2: 0 -> 0 [state SNK_READY, polarity 0, disconnected]
	[ 2087.028574] state change SNK_READY -> SNK_UNATTACHED [rev3 NONE_AMS]
	[ 2087.028585] disable BIST MODE TESTDATA
	[ 2087.029540] Setting usb_comm capable false
	[ 2087.031079] Setting voltage/current limit 0 mV 0 mA
	[ 2087.031116] polarity 0
	[ 2087.033294][  T151] emdoor: tcpm_set_polarity typec positive
	[ 2087.033323] Requesting mux state 0, usb-role 0, orientation 0
	[ 2087.034933] Start toggling
	[ 2087.035701] state change SNK_UNATTACHED -> TOGGLING [rev3 NONE_AMS]
	[ 2087.046906][  T152] =================> tcpci_irq -> status[0x02]
	[ 2087.048083] VBUS off
	[ 2087.048095] VBUS VSAFE0V

从log内,进一步分析整个tcpm的运行流程,总结了出如下流程图:
在这里插入图片描述

同样关于插入的过程也总结了如下流程图:

图片的流程图只画了主体,一些细枝末节没有过多去描述其内容。

如有错误还请指正,感谢!!

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

坚持不秃0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值